26th_Meetup_of_PLSSUG_WROCLAW-ColumnStore_Indexes_byBeataZalewa_scripts

356 views

Published on

Published in: Education, Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
356
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

26th_Meetup_of_PLSSUG_WROCLAW-ColumnStore_Indexes_byBeataZalewa_scripts

  1. 1. 1. TworzenieColumnStore.sql-- to ćwiczenie możemy wykonać w kontekście dowolnej bazy danych, tutajAdventureWorks2012USE AdventureWorks2012GO--stworzenie tabeliCREATETABLE dbo.ColumnStoreIndex( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2))-- Stworzenie indeksu klastrowegoCREATECLUSTEREDINDEX IX_Column1 ON dbo.ColumnStoreIndex(Column1)-- stworzenie indeksu nieklastrowego COLUMNSTORECREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4ON dbo.ColumnStoreIndex(Column2,Column3,Column4)--czyszczenie bazy danychDROPINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStoreIndexGODROPTABLE dbo.ColumnStoreIndexGO 2. UpdateTabeli.sqlUSE AdventureWorks2012GO--stworzenie tabeliCREATETABLE dbo.ColumnStore( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2))-- stworzenie indeksu klastrowegoCREATECLUSTEREDINDEX IX_Column1 ON dbo.ColumnStore(Column1)-- stworzenie indeksu nieklastrowego COLUMNSTORECREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4ON dbo.ColumnStore(Column2,Column3,Column4)--próba wstawienia rekordu (błąd)Insertinto dbo.ColumnStore Values(Col2 Val1,GETDATE(),10.23)-- Wyłączenie indeksu columnstore zanim wykonany instrukcję INSERTALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore DISABLE;--wstawienie rekorduINSERTINTO dbo.ColumnStore VALUES(Col2 Val1,GETDATE(),10.23)
  2. 2. INSERTINTO dbo.ColumnStore VALUES(Col2 Val2,GETDATE(),10.24)-- przebudowa indeksu columnstore co wykonaniu instrukcji INSERTALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore REBUILD;--czyszczenie bazy danychDROPINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStoreGODROPTABLE dbo.ColumnStoreGO-----------------Alternatywnie my możemy najpierw stworzyć tabelę, potem dodać rekord ipotem dopiero stworzyć indeks columnstore--stworzenie tabeliCREATETABLE dbo.ColumnStore1( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2))--Wstawienie rekorduINSERTINTO dbo.ColumnStore1 VALUES(Col2 Val1,GETDATE(),10.23)INSERTINTO dbo.ColumnStore1 VALUES(Col2 Val2,GETDATE(),10.24)--stworzenie indeksów-- stworzenie indeksu klastrowegoCREATECLUSTEREDINDEX IX_Column1 ON dbo.ColumnStore1(Column1)-- stworzenie indeksu nieklastrowego COLUMNSTORECREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4ON dbo.ColumnStore1(Column2,Column3,Column4)--ten sposób zadziała tylko za pierwszym razem (wykonanie insertów przedstworzeniem indeksu columnstore).--próba wykonania tej instrukcji, spowoduje wyżwietlenie błęduUPDATE dbo.ColumnStore1SET Column2 =Updated ValueWHERE Column1 = 1-- aby można wykonać tą aktualizację należy wyłączyć indeks columnstorezanim spróbujemy wykonać UPDATEALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore1 DISABLE;UPDATE dbo.ColumnStore1SET Column2 =Updated ValueWHERE Column1 = 1-- przebudowa indeksu columnstore jak wykona się instrukcja INSERTALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore1 REBUILD;SELECT*FROM dbo.ColumnStore1-- Czyszczenie bazy danychDROPINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore1GODROPTABLE dbo.ColumnStore1GO
  3. 3. 3. Ograniczenia.sql--1. Nie można stworzyć klastrowego indeksu ColumnStoreUSE AdventureWorks2012GO--stworzenie tabeliCREATETABLE dbo.ColumnStoreIndex( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2))-- próba stworzenia indeksu klastrowego COLUMNSTORECREATECLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4ON dbo.ColumnStoreIndex(Column2,Column3,Column4)-- Czyszczenie bazy danychDROPTABLE dbo.ColumnStoreIndex--2. Nie można stworzyć nieklastrowego indeksu COLUMNSTORE z opcją INCLUDEUSE AdventureWorks2012GO--stworzenie tabeliCREATETABLE dbo.ColumnStoreIndex( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2))-- próba stworzenia nieklastrowanego indeksu COLUMNSTORECREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2ON dbo.ColumnStoreIndex(Column2)INCLUDE (Column1 ,Column3 ,Column4 )GO-- Czyszczenie bazy danychDROPTABLE dbo.ColumnStoreIndex--3.Nie można stworzyć indeksu ColumnStore na kolumnach wyliczanych(computed)--stworzenie tabeliCREATETABLE dbo.ColumnStoreIndex( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 INT, Column5 AS (Column1+Column4)-- kolumna wyliczana)
  4. 4. -- stworzenie nieklastrowego indeksu COLUMNSTORECREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2ON dbo.ColumnStoreIndex(Column5)-- Czyszczenie bazy danychDROPTABLE dbo.ColumnStoreIndex--4. Nie można stworzyć wielu indeksów ColumnStore--stworzenie tabeliCREATETABLE dbo.ColumnStoreIndex( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2))-- Próba stworzenia kliku indeksów COLUMNSTORECREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2ON dbo.ColumnStoreIndex(Column2)CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C3ON dbo.ColumnStoreIndex(Column3)-- Czyszczenie bazy danychDROPTABLE dbo.ColumnStoreIndex 4. TestWydajności.sqlUSE AdventureWorks2012GO-- stworzenie nowej tabeliCREATETABLE dbo.TestColumnStoreIndexes([SalesOrderID] [int] NOTNULL,[SalesOrderDetailID] [int] NOTNULL,[CarrierTrackingNumber] [nvarchar](25)NULL,[OrderQty] [smallint] NOTNULL,[ProductID] [int] NOTNULL,[SpecialOfferID] [int] NOTNULL,[UnitPrice] [money] NOTNULL,[UnitPriceDiscount] [money] NOTNULL,[LineTotal] [numeric](38, 6)NOTNULL,[rowguid] [uniqueidentifier] NOTNULL,[ModifiedDate] [datetime] NOTNULL)ON [PRIMARY]GO-- stworzenie indeksu klastrowegoCREATECLUSTEREDINDEX CL_TestColumnStoreIndexes ONdbo.TestColumnStoreIndexes( [SalesOrderDetailID])GO-- stworzenie tabeli do testów-- To zapytanie może się wykonywać dożć długo
  5. 5. INSERTINTO dbo.TestColumnStoreIndexesSELECT S1.*FROM Sales.SalesOrderDetail S1GO 100-- wstawi mi 12 131 700 rekordów-- select * FROM dbo.TestColumnStoreIndexes-- pierwszy test wydajnożciowy-- wykorzystanie SET STATISTICS IO ON dla zmierzenia ilożci operacji IO,których potrzeba do wykonania zapytania.-- w pierwszym teżcie uruchomimy zapytanie, które będzie używało zwykłychindeksów.-- należy zanotować użycie operacji IO w zapytaniu-- potem sprawdzimy to samo przy użyciu indeksów ColumnStore i znowuzmierzenie operacji IO-- Test wydajnożci-- Porównanie zwykłego indeksu z indeksem ColumnStoreUSE AdventureWorks2012GOSETSTATISTICSIOONGO--włączenie Actual Execution Plan-- Select na tabeli ze zwykłym indeksem nieklastrowymSELECT ProductID,SUM(UnitPrice) SumUnitPrice,AVG(UnitPrice) AvgUnitPrice,SUM(OrderQty) SumOrderQty,AVG(OrderQty) AvgOrderQtyFROM dbo.TestColumnStoreIndexesGROUPBY ProductIDORDERBY ProductIDGO--Table dbo.TestColumnStoreIndexes. Scan count 1, logical reads 345590,physical reads 0, read-ahead reads 0.--stworzenie indeksu ColumnStoreCREATENONCLUSTERED COLUMNSTORE INDEX IX_TestColumnStoreIndexesON TestColumnStoreIndexes(UnitPrice, OrderQty, ProductID)GO-- Select na tabeli z indeksem ColumnstoreSELECT ProductID,SUM(UnitPrice) SumUnitPrice,AVG(UnitPrice) AvgUnitPrice,SUM(OrderQty) SumOrderQty,AVG(OrderQty) AvgOrderQtyFROM [dbo].TestColumnStoreIndexesGROUPBY ProductIDORDERBY ProductIDGO-- wydajność radykalnie wzrosła po stworzeniu indeksu ColumnStore Index.-- Ilożć stron, które zapytanie miało odczytać została drastyczniezredukowana--jako że kolumny, które są potrzebne do zapytania są przechowywane na tejsamej stronie i zapytanie nie musi przeszukiwac każdej-- pojedynczej kolumny, aby odczytać te strony.--jeżli włączymy execution plan i porównamy, możemy zobaczyć, że wydajnośćindeksu ColumnStore jest dużo lepsza niż zwykłego indeksu--nieklastrowanego w tym przypadku.-- Czyszczenie bazy danychDROPINDEX [IX_TestColumnStoreIndexes] ON dbo.TestColumnStoreIndexesGOTRUNCATETABLE dbo.TestColumnStoreIndexes
  6. 6. GODROPTABLE dbo.TestColumnStoreIndexesGO 5. BatchExecutionMode.sqlUSE AdventureWorks2012;GO--stworzenie funkcji partycjonującejCREATEPARTITIONFUNCTION [ByOrderDateMonthPF](int)ASRANGERIGHTFORVALUES ( 20050701, 20050801, 20050901, 20051001, 20051101, 20051201, 20060101, 20060201, 20060301, 20060401, 20060501, 20060601, 20060701, 20060801, 20060901, 20061001, 20061101, 20061201, 20070101, 20070201, 20070301, 20070401, 20070501, 20070601, 20070701, 20070801, 20070901, 20071001, 20071101, 20071201, 20080101, 20080201, 20080301, 20080401, 20080501, 20080601, 20080701, 20080801, 20080901, 20081001, 20081101, 20081201)GO--stworzenie schematu partycjonującegoCREATEPARTITION SCHEME [ByOrderDateMonthRange]ASPARTITION [ByOrderDateMonthPF]ALLTO ([PRIMARY])GO-- stworzenie partycjonującej wersji tabeli FactResellerSalesCREATETABLE [dbo].[FactResellerSalesPtnd]( [ProductKey] [int] NOTNULL, [OrderDateKey] [int] NOTNULL, [DueDateKey] [int] NOTNULL, [ShipDateKey] [int] NOTNULL, [ResellerKey] [int] NOTNULL, [EmployeeKey] [int] NOTNULL, [PromotionKey] [int] NOTNULL, [CurrencyKey] [int] NOTNULL, [SalesTerritoryKey] [int] NOTNULL, [SalesOrderNumber] [nvarchar](20)NOTNULL, [SalesOrderLineNumber] [tinyint] NOTNULL, [RevisionNumber] [tinyint] NULL, [OrderQuantity] [smallint] NULL, [UnitPrice] [money] NULL, [ExtendedAmount] [money] NULL, [UnitPriceDiscountPct] [float] NULL, [DiscountAmount] [float] NULL, [ProductStandardCost] [money] NULL, [TotalProductCost] [money] NULL, [SalesAmount] [money] NULL, [TaxAmt] [money] NULL, [Freight] [money] NULL, [CarrierTrackingNumber] [nvarchar](25)NULL, [CustomerPONumber] [nvarchar](25)NULL,
  7. 7. [OrderDate] datetimeNULL, [DueDate] datetimeNULL, [ShipDate] datetimeNULL)ON ByOrderDateMonthRange(OrderDateKey);GO-- skopiowanie danych z tabeli FactResellerSales do nowej tabeliINSERTINTO dbo.FactResellerSalesPtnd WITH(TABLOCK)SELECT*FROM AdventureWorksDW2012.dbo.FactResellerSales;GO-- stworzenie indeksu columnstoreCREATENONCLUSTERED COLUMNSTORE INDEX [csindx_FactResellerSalesPtnd]ON [FactResellerSalesPtnd]( [ProductKey], [OrderDateKey], [DueDateKey], [ShipDateKey], [ResellerKey], [EmployeeKey], [PromotionKey], [CurrencyKey], [SalesTerritoryKey], [SalesOrderNumber], [SalesOrderLineNumber], [RevisionNumber], [OrderQuantity], [UnitPrice], [ExtendedAmount], [UnitPriceDiscountPct], [DiscountAmount], [ProductStandardCost], [TotalProductCost], [SalesAmount], [TaxAmt], [Freight], [CarrierTrackingNumber], [CustomerPONumber]);--wykonanie następującego zapytania (podejrzenie planu wykonania)SELECT SalesTerritoryKey,SUM(ExtendedAmount)AS SalesByTerritoryFROM FactResellerSalesPtndGROUPBY SalesTerritoryKey;--możemy zauważyć, że actual i estimated execution mode jest Row (linie 3 i4 na liżcie Properties indeksu).--Row execution mode został wybrany ponieważ tabela nie jest wystarczającoduża, aby wywołać batch execution mode.--możemy użyć nieudokumentowanych opcji ROWCOUNT (dla 10 mln wierszy) iPAGECOUNT (dla 1 mln stron) do instrukcji UPDATE STATISTICS,--aby zasymulować, jakby się to wykonało na większej tabeliUPDATESTATISTICS FactResellerSalesPtnd WITHROWCOUNT= 10000000,PAGECOUNT=1000000--usunięcie z cacheu starego planu wykonania
  8. 8. DBCC FREEPROCCACHE--wykonanie jeszcze raz tego zapytaniaSELECT SalesTerritoryKey,SUM(ExtendedAmount)AS SalesByTerritoryFROM FactResellerSalesPtndGROUPBY SalesTerritoryKey;--tym razem we włażciwożciach Columnstore Index Scan możemy zobaczyć, żewykonał to używać the batch execution mode--możemy także użyć nowego hinta IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX dowyłaczenia użycia indeksu columnstore.SELECT SalesTerritoryKey,SUM(ExtendedAmount)AS SalesByTerritoryFROM FactResellerSalesPtndGROUPBY SalesTerritoryKeyOPTION (IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX);-- teraz plan wykonania pokazuje Nam skan tabeli FactResellerSalesPtnd, bezużycia indeksu columnstore.-- usunięcie tabeliDROPTABLE FactResellerSalesPtndGODROPPARTITION SCHEME ByOrderDateMonthRangeGODROPPARTITIONFUNCTION ByOrderDateMonthPFGO

×