Wednesday, August 15, 2007

Partitions i SQL 2005

SQL 2005 innehåller en funktion som heter Partition vilket innebär att man helt enkelt dela ut en tabell eller index på flera filgrupper. Jag tänkte försöka förklara detta lite närmre här.

Låt oss säga att vi har en tabell som innehåller vanligt orderdata och en id kolumn. I detta exemplet så vill jag dela upp tabellen på id kolumnen. Order från 1 till 1000000 skall hamna i en fil grupp 1000001 till 2000000 skall hamna i filgrupp två osv och data över 3000000 i den sista filgruppen . Då börja vi med att skapa de fysiska databsfilerna och sedan själva filgrupperna. Vitsen med Partition är att sprida ut tabellen på flera ställen så att servern kan nyttja fler läsarmar i disksystemet. I detta fallet så skapade jag fyra st och lät dom heta DataFile1 osv.

Nu är det dags att skapa själva Partitionen (eller vad man nu skall kalla den på svenska).

Först funktionen:
CREATE PARTITION FUNCTION Function_tabellnamnet (INT)
AS RANGE RIGHT FOR VALUES (1000000, 2000000, 3000000)


Sedan Schemat:
CREATE PARTITION SCHEME Schema_tabellnamnet
AS PARTITION Function_tabellnamnet
TO (DataFile1, DataFile2, DataFile3, DataFile4)


Nu kan vi skapa själva tabellen:
CREATE TABLE Test (Id INT, OrderName VARCHAR(20), Date (datetime)) ON Schema_tabellnamnet (Id)

Nu är det bara att fylla tabellen med data och SQL kommer dela upp datat på flera filer och få möjlighet att läsa från fler ställen vilket förhoppningsvis kan öka prestandarden i systemet.
Vill man se hur datat är uppdelat mellan de olika partitionerna kan man göra det med följande kommando:
SELECT *
FROM sys.partitions
WHERE OBJECT_ID = OBJECT_ID('tabellnamn')

Eller:
select $partition.Function_tabellnamnet(id) as partitionNum, count(*)
from dbo.Test
group by $partition. Function_tabellnamnet (id)

Partition går även att använda på tex datum kolumner om det passa bättre. Kan vara bra om man tex vill lägga över gammalt data som inte används så frekvent till en annan disk. Finns en hel del möjligheter att pröva.

Monday, August 13, 2007

Medianvärde

Satt och klurade på att få ut medianvärdet från en pris column. Lyckades inte men efter lite googlande så hittade jag en fungerande sqlsats skriven utav Anjuna Moon i idg-s forum. För mig verka det fungera.

SELECT AVG(C1) AS Expr1
FROM (SELECT MAX(Price) C1
FROM (SELECT TOP 50 PERCENT Price
FROM [object]where type = 'värde'
ORDER BY Price) T1
UNION ALL
SELECT MIN(Price) C1
FROM (SELECT TOP 50 PERCENT Price
FROM [object] where type = 'värde'
ORDER BY Price DESC) T1) T3