Descoperirea
partitiilor pas cu pas
Partitiile sunt mecanismul prin
care in SQL 2005 se pot distribui date ale unui tabel pe mai multe
filegroup-uri pe baza unui criteriu de impartire. Beneficiile utilizarii
acestuia sunt mari , lista lor o gasiti sigur prin MSDN (aici Cristi Lefter sau
altcineva dintre dvs. ma puteti ajuta cu un link catre astfel de resurse).
In continuare vi se va desfasura
un film al incercarilor mele facute pentru testarea acestui mecanism. Daca este
prost sau mai trebuie imbunatatit, dumneavoastra o puteti spune, insa sigur
puteti trece de la postura de spectator la cea de regizor, masinist, sunetist,
cascador sau ce mai vreti …
Folosesc
aceeasi baza de date “chioara” facuta candva intr-un articol. Citind
“scenariul” oferit de Books Online aflu ca trebuie facuta o functie pentru
partitie:
CREATE PARTITION FUNCTION
[myRangePF1](int) AS RANGE LEFT FOR VALUES (1, 100, 1000)
Aceasta se numeste “myRangePF1” si imparte datele in 4
partitii :
Partitia 1 intregi pana la borna 1 (inclusiv 1 pentru ca
apare LEFT)
Partitia 2 intregi intre 1 si 100 inclusiv
Partitia 3 intregi intre 100 si 1000 inclusiv
Partitia 4 intregi peste 1000
(daca as fi folosit RIGHT in loc de LEFT am fi avut de
exemplu
Partitia 3 intregi intre 100 inclusiv si 1000)
Mai departe trebuie sa fac o asociere intre aceste
zone unde se vor duce datele si filegroup-uri. Pentru asta construiesc intai 4
filegroupuri test1fg, test2fg, test3fg, test4fg si generez o schema de partitie
care face asocierea:
CREATE PARTITION SCHEME
[myRangePS1] AS PARTITION
[myRangePF1] TO ([test1fg], [test2fg],
[test3fg], [test4fg])
Acuma bucataria e gata, mai trebuie sa pun un tabel sa se
foloseasca de aceste lucruri; tabelul creat mai jos face ca pe baza coloanei
“clasa” sa se faca impartirea datelor:
USE

GO
CREATE
TABLE [dbo].[test](
[id] [int] IDENTITY(1,1) NOT NULL,
[nume] [varchar](50) COLLATE
SQL_Latin1_General_CP1_CI_AS NULL,
[clasa] [int] NULL
)
ON [myRangePS1]([clasa])
GO
SET
ANSI_PADDING OFF
Mai departe
ma joc inserand o multime de date in tabelul nostru
declare @i int
declare @nume1 varchar(20)
set @i=0
while @i<2000
begin
set @i=@i+1
set @nume1='Gigi'+cast(@i as varchar(4))
INSERT INTO
.[dbo].[test]
([nume]
,[clasa])
VALUES (@nume1
,@i)
end
Pentru a vedea ce date am si unde le am apelez la functia PARTITION.myRangePF1(clasax) care da partitia unde se depun datele ce fac
parte din clasa “clasax”, si, prin interogarea urmatoare
USE a ;
GO
SELECT $PARTITION.myRangePF1(clasa) AS Partition,
COUNT(*) AS
[COUNT] FROM dbo.test
GROUP BY $PARTITION.myRangePF1(clasa)
ORDER BY Partition ;
Rezulta
un numar de date ca in tabelul urmator :
Partition COUNT
-----------
-----------
1 1
2 99
3 900
4 1000
(4 row(s)
affected)
De asemenea pentru a vedea “icrele” depuse in partitia
numarul 3 se poate lansa
select * from dbo.test
where $partition.myrangepf1(clasa)=3
Cu partitiile se pot face urmatoarele operatii:
- Switching
- Merging
- Splitting
Daca ultimele 2 sunt un pic mai
transparente(merging=unire a 2 partitii, splitting=descompunere a unei
partitii) haideti sa vedem ce inseamna switching:
Iata ce date avem pe partitia nr 2
select * from test
where $PARTITION.myrangepf1(clasa)=2
id nume clasa
-----------
-------------------------------------------------- -----------
2 Gigi2 2
3 Gigi3 3
…
100 Gigi100 100
(99 row(s)
affected)
Creez un nou tabel test2 identic cu test in filegroupul
test2fg, si inserez un rand oarecare in tabel dupa care pornesc switching:
ALTER TABLE
test SWITCH PARTITION 2 TO test2 ;
Msg 4905,
Level 16, State 1, Line 1
ALTER TABLE SWITCH statement failed. The target table
'a.dbo.test2' must be empty.
Asta inseamna ca test2 trebuie sa fie gol pentru a face
switching.
Sterg acel rand si relansez comanda de switching, apoi vad
ce date sunt pe aceasta partitie:
id nume
clasa
-----------
-------------------------------------------------- -----------
(0 row(s)
affected)
Asta inseamna ca prin switching datele de pe partitia
initiala sunt pierdute.
Si ca sa nu fiu dator cu celelalte operatii:
ALTER PARTITION FUNCTION
myRangePF1()
MERGE RANGE (100)
Da urmatoarele rezultate:
Partition COUNT
-----------
-----------
1 1
2 999
3 1000
(3 row(s)
affected)
Asta inseamna ca partitiile 2 si 3 s-au unit (99 + 900), iar
ALTER PARTITION FUNCTION
myRangePF1()
SPLIT RANGE (500)
Ne da
Msg 7707,
Level 16, State 1, Line 1
The
associated partition function 'myRangePF1' generates more partitions than there
are file groups mentioned in the scheme 'myRangePS1'.
Oops !
Dupa
cateva cautari aflu ca trebuia sa mai am un filegroup disponibil asa ca il
construiesc si pe test5fg , modific schema cu
ALTER PARTITION SCHEME
myRangePS1
NEXT USED test5fg
astfel ca partitia sa recunoasca noul filegroup dupa care
comanda de splitare functioneaza corect.
The
End
Gheorghe Ciubuc,SQL Server Influencer, MCP(SQL 2000), MCTS (SQL Server 2005) , OCA(Oracle 9i), Sybase(Brainbench)