1. TworzenieColumnStore.sql


-- to ćwiczenie możemy wykonać w kontekście dowolnej bazy danych, tutaj
AdventureWorks2012
USE AdventureWorks2012
GO
--stworzenie tabeli
CREATETABLE dbo.ColumnStoreIndex(
      Column1 INTIDENTITY,
      Column2 VARCHAR(50),
      Column3 DATETIME,
      Column4 NUMERIC(16,2)
)
-- Stworzenie indeksu klastrowego
CREATECLUSTEREDINDEX IX_Column1 ON dbo.ColumnStoreIndex(Column1)
-- stworzenie indeksu nieklastrowego COLUMNSTORE
CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4
ON dbo.ColumnStoreIndex(Column2,Column3,Column4)

--czyszczenie bazy danych
DROPINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStoreIndex
GO
DROPTABLE dbo.ColumnStoreIndex
GO




 2. UpdateTabeli.sql


USE AdventureWorks2012
GO

--stworzenie tabeli
CREATETABLE dbo.ColumnStore(
      Column1 INTIDENTITY,
      Column2 VARCHAR(50),
      Column3 DATETIME,
      Column4 NUMERIC(16,2)
)
-- stworzenie indeksu klastrowego
CREATECLUSTEREDINDEX IX_Column1 ON dbo.ColumnStore(Column1)

-- stworzenie indeksu nieklastrowego COLUMNSTORE
CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4
ON 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ę INSERT
ALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore DISABLE;

--wstawienie rekordu
INSERTINTO dbo.ColumnStore VALUES('Col2 Val1',GETDATE(),10.23)
INSERTINTO dbo.ColumnStore VALUES('Col2 Val2',GETDATE(),10.24)

-- przebudowa indeksu columnstore co wykonaniu instrukcji INSERT
ALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore REBUILD;

--czyszczenie bazy danych
DROPINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore
GO
DROPTABLE dbo.ColumnStore
GO

---------------
--Alternatywnie my możemy najpierw stworzyć tabelę, potem dodać rekord i
potem dopiero stworzyć indeks columnstore

--stworzenie tabeli
CREATETABLE dbo.ColumnStore1(
      Column1 INTIDENTITY,
      Column2 VARCHAR(50),
      Column3 DATETIME,
      Column4 NUMERIC(16,2)
)
--Wstawienie rekordu
INSERTINTO dbo.ColumnStore1 VALUES('Col2 Val1',GETDATE(),10.23)
INSERTINTO dbo.ColumnStore1 VALUES('Col2 Val2',GETDATE(),10.24)

--stworzenie indeksów
-- stworzenie indeksu klastrowego
CREATECLUSTEREDINDEX IX_Column1 ON dbo.ColumnStore1(Column1)

-- stworzenie indeksu nieklastrowego COLUMNSTORE
CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4
ON dbo.ColumnStore1(Column2,Column3,Column4)

--ten sposób zadziała tylko za pierwszym razem (wykonanie insertów przed
stworzeniem indeksu columnstore).

--próba wykonania tej instrukcji, spowoduje wyżwietlenie błędu

UPDATE dbo.ColumnStore1
SET Column2 ='Updated Value'
WHERE Column1 = 1

-- aby można wykonać tą aktualizację należy wyłączyć indeks columnstore
zanim spróbujemy wykonać UPDATE
ALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore1 DISABLE;

UPDATE dbo.ColumnStore1
SET Column2 ='Updated Value'
WHERE Column1 = 1

-- przebudowa indeksu columnstore jak wykona się instrukcja INSERT
ALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore1 REBUILD;

SELECT*FROM dbo.ColumnStore1

-- Czyszczenie bazy danych
DROPINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore1
GO
DROPTABLE dbo.ColumnStore1
GO
3. Ograniczenia.sql


--1. Nie można stworzyć klastrowego indeksu ColumnStore
USE AdventureWorks2012
GO

--stworzenie tabeli
CREATETABLE dbo.ColumnStoreIndex(
      Column1 INTIDENTITY,
      Column2 VARCHAR(50),
      Column3 DATETIME,
      Column4 NUMERIC(16,2)
)

-- próba stworzenia indeksu klastrowego COLUMNSTORE
CREATECLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4
ON dbo.ColumnStoreIndex(Column2,Column3,Column4)

-- Czyszczenie bazy danych
DROPTABLE dbo.ColumnStoreIndex

--2. Nie można stworzyć nieklastrowego indeksu COLUMNSTORE z opcją INCLUDE
USE AdventureWorks2012
GO

--stworzenie tabeli
CREATETABLE dbo.ColumnStoreIndex(
      Column1 INTIDENTITY,
      Column2 VARCHAR(50),
      Column3 DATETIME,
      Column4 NUMERIC(16,2)
)

-- próba stworzenia nieklastrowanego indeksu COLUMNSTORE
CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2
ON dbo.ColumnStoreIndex(Column2)
INCLUDE (Column1 ,Column3 ,Column4 )
GO

-- Czyszczenie bazy danych
DROPTABLE dbo.ColumnStoreIndex

--3.Nie można stworzyć indeksu ColumnStore na kolumnach wyliczanych
(computed)

--stworzenie tabeli
CREATETABLE dbo.ColumnStoreIndex(
      Column1 INTIDENTITY,
      Column2 VARCHAR(50),
      Column3 DATETIME,
      Column4 INT,
      Column5 AS (Column1+Column4)-- kolumna wyliczana
)
-- stworzenie nieklastrowego indeksu COLUMNSTORE
CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2
ON dbo.ColumnStoreIndex(Column5)

-- Czyszczenie bazy danych
DROPTABLE dbo.ColumnStoreIndex

--4. Nie można stworzyć wielu indeksów ColumnStore

--stworzenie tabeli
CREATETABLE dbo.ColumnStoreIndex(
      Column1 INTIDENTITY,
      Column2 VARCHAR(50),
      Column3 DATETIME,
      Column4 NUMERIC(16,2)
)

-- Próba stworzenia kliku indeksów COLUMNSTORE
CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2
ON dbo.ColumnStoreIndex(Column2)

CREATENONCLUSTERED COLUMNSTORE INDEX   IX_CS_C3
ON dbo.ColumnStoreIndex(Column3)

-- Czyszczenie bazy danych
DROPTABLE dbo.ColumnStoreIndex




 4. TestWydajności.sql


USE AdventureWorks2012
GO
-- stworzenie nowej tabeli
CREATETABLE 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 klastrowego
CREATECLUSTEREDINDEX CL_TestColumnStoreIndexes ON
dbo.TestColumnStoreIndexes
( [SalesOrderDetailID])
GO
-- stworzenie tabeli do testów
-- To zapytanie może się wykonywać dożć długo
INSERTINTO dbo.TestColumnStoreIndexes
SELECT S1.*
FROM Sales.SalesOrderDetail S1
GO 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łych
indeksów.
-- należy zanotować użycie operacji IO w zapytaniu
-- potem sprawdzimy to samo przy użyciu indeksów ColumnStore i znowu
zmierzenie operacji IO

-- Test wydajnożci
-- Porównanie zwykłego indeksu z indeksem ColumnStore
USE AdventureWorks2012
GO
SETSTATISTICSIOON
GO
--włączenie Actual Execution Plan
-- Select na tabeli ze zwykłym indeksem nieklastrowym
SELECT ProductID,SUM(UnitPrice) SumUnitPrice,AVG(UnitPrice) AvgUnitPrice,
SUM(OrderQty) SumOrderQty,AVG(OrderQty) AvgOrderQty
FROM dbo.TestColumnStoreIndexes
GROUPBY ProductID
ORDERBY ProductID
GO
--Table 'dbo.TestColumnStoreIndexes'. Scan count 1, logical reads 345590,
physical reads 0, read-ahead reads 0.
--stworzenie indeksu ColumnStore
CREATENONCLUSTERED COLUMNSTORE INDEX IX_TestColumnStoreIndexes
ON TestColumnStoreIndexes
(UnitPrice, OrderQty, ProductID)
GO
-- Select na tabeli z indeksem Columnstore
SELECT ProductID,SUM(UnitPrice) SumUnitPrice,AVG(UnitPrice) AvgUnitPrice,
SUM(OrderQty) SumOrderQty,AVG(OrderQty) AvgOrderQty
FROM [dbo].TestColumnStoreIndexes
GROUPBY ProductID
ORDERBY ProductID
GO

-- wydajność radykalnie wzrosła po stworzeniu indeksu ColumnStore Index.
-- Ilożć stron, które zapytanie miało odczytać została drastycznie
zredukowana
--jako że kolumny, które są potrzebne do zapytania są przechowywane na tej
samej 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 danych
DROPINDEX [IX_TestColumnStoreIndexes] ON dbo.TestColumnStoreIndexes
GO
TRUNCATETABLE dbo.TestColumnStoreIndexes
GO
DROPTABLE dbo.TestColumnStoreIndexes
GO




  5. BatchExecutionMode.sql


USE AdventureWorks2012;
GO

--stworzenie funkcji partycjonującej
CREATEPARTITIONFUNCTION [ByOrderDateMonthPF](int)ASRANGERIGHT
FORVALUES (
    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ącego
CREATEPARTITION SCHEME [ByOrderDateMonthRange]
ASPARTITION [ByOrderDateMonthPF]
ALLTO ([PRIMARY])
GO

-- stworzenie partycjonującej wersji tabeli FactResellerSales
CREATETABLE [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,
[OrderDate] datetimeNULL,
    [DueDate] datetimeNULL,
    [ShipDate] datetimeNULL
)ON ByOrderDateMonthRange(OrderDateKey);
GO

-- skopiowanie danych z tabeli FactResellerSales do nowej tabeli
INSERTINTO dbo.FactResellerSalesPtnd WITH(TABLOCK)
SELECT*FROM AdventureWorksDW2012.dbo.FactResellerSales;
GO

-- stworzenie indeksu columnstore
CREATENONCLUSTERED 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 SalesByTerritory
FROM FactResellerSalesPtnd
GROUPBY SalesTerritoryKey;


--możemy zauważyć, że actual i estimated execution mode jest Row (linie 3 i
4 na liżcie Properties indeksu).
--Row execution mode został wybrany ponieważ tabela nie jest wystarczająco
duża, aby wywołać batch execution mode.
--możemy użyć nieudokumentowanych opcji ROWCOUNT (dla 10 mln wierszy) i
PAGECOUNT (dla 1 mln stron) do instrukcji UPDATE STATISTICS,
--aby zasymulować, jakby się to wykonało na większej tabeli

UPDATESTATISTICS FactResellerSalesPtnd WITHROWCOUNT= 10000000,PAGECOUNT=
1000000

--usunięcie z cache'u starego planu wykonania
DBCC FREEPROCCACHE
--wykonanie jeszcze raz tego zapytania
SELECT SalesTerritoryKey,SUM(ExtendedAmount)AS SalesByTerritory
FROM FactResellerSalesPtnd
GROUPBY SalesTerritoryKey;

--tym razem we włażciwożciach Columnstore Index Scan możemy zobaczyć, że
wykonał to używać the batch execution mode


--możemy także użyć nowego hinta IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX do
wyłaczenia użycia indeksu columnstore.
SELECT SalesTerritoryKey,SUM(ExtendedAmount)AS SalesByTerritory
FROM FactResellerSalesPtnd
GROUPBY SalesTerritoryKey
OPTION (IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX);

-- teraz plan wykonania pokazuje Nam skan tabeli FactResellerSalesPtnd, bez
użycia indeksu columnstore.
-- usunięcie tabeli
DROPTABLE FactResellerSalesPtnd
GO
DROPPARTITION SCHEME ByOrderDateMonthRange
GO
DROPPARTITIONFUNCTION ByOrderDateMonthPF
GO

More Related Content

PDF
Architektura ngrx w angular 2+
PDF
SQLDay2013_Denny Cherry - Table indexing for the .NET Developer
PDF
SQL DAY 2012 | DEV Track | Session 9 - Data Mining Analiza Przepływowa by M.S...
PDF
SQLDay2013_GrzegorzStolecki_RealTimeOLAP
PDF
SQLDay2013_GrzegorzStolecki_KonsolidacjaBI
PDF
SQLDay2011_Sesja02_Collation_Marek Adamczuk
PDF
SQLDay2013_Denny Cherry - SQLServer2012inaHighlyAvailableWorld
PDF
SQLDay2013_DennyCherry_GettingSQLServiceBrokerUp&Running
Architektura ngrx w angular 2+
SQLDay2013_Denny Cherry - Table indexing for the .NET Developer
SQL DAY 2012 | DEV Track | Session 9 - Data Mining Analiza Przepływowa by M.S...
SQLDay2013_GrzegorzStolecki_RealTimeOLAP
SQLDay2013_GrzegorzStolecki_KonsolidacjaBI
SQLDay2011_Sesja02_Collation_Marek Adamczuk
SQLDay2013_Denny Cherry - SQLServer2012inaHighlyAvailableWorld
SQLDay2013_DennyCherry_GettingSQLServiceBrokerUp&Running

Viewers also liked (18)

PDF
SQLDay2013_PawełPotasiński_GeografiaSQLServer2012
PDF
SQLDay2013_MarcinSzeliga_SQLServer2012FastTrackDWReferenceArchitectures
PDF
CISSPDAY 2011 - 2 AM A Disaster just Began
PDF
38Spotkanie_PLSSUGweWroclawiu_Keynote
PDF
SQL DAY 2012 | DEV Track | Session 6 - Master Data Management by W.Bielski 6 ...
PDF
SQLDay2013_MaciejPilecki_Lock&Latches
PDF
SQLDay2013_ChrisWebb_SSASDesignMistakes
PDF
SQLDay2013_MarekAdamczuk_Kursory
PDF
SQLDay2013_ChrisWebb_DAXMD
PDF
SQLDay2013_MarcinSzeliga_StoredProcedures
PDF
SQLDay2013_PawełPotasiński_ParallelDataWareHouse
PPTX
Sql day2015 fts
PDF
SQLDay2013_ChrisWebb_CubeDesign&PerformanceTuning
PDF
GoldenLine.pl - Od Startupu do... Startupu :-)
PDF
SQL DAY 2012 | DEV Track | Session 8 - Getting Dimension with Data by C.Tecta...
PDF
Maintenance_Plans_Zupełnie_Znienacka
PPT
Kompletny przewodnik po SQL injection dla developerów PHP (i nie tylko)
PPT
Śniadanie Daje Moc
SQLDay2013_PawełPotasiński_GeografiaSQLServer2012
SQLDay2013_MarcinSzeliga_SQLServer2012FastTrackDWReferenceArchitectures
CISSPDAY 2011 - 2 AM A Disaster just Began
38Spotkanie_PLSSUGweWroclawiu_Keynote
SQL DAY 2012 | DEV Track | Session 6 - Master Data Management by W.Bielski 6 ...
SQLDay2013_MaciejPilecki_Lock&Latches
SQLDay2013_ChrisWebb_SSASDesignMistakes
SQLDay2013_MarekAdamczuk_Kursory
SQLDay2013_ChrisWebb_DAXMD
SQLDay2013_MarcinSzeliga_StoredProcedures
SQLDay2013_PawełPotasiński_ParallelDataWareHouse
Sql day2015 fts
SQLDay2013_ChrisWebb_CubeDesign&PerformanceTuning
GoldenLine.pl - Od Startupu do... Startupu :-)
SQL DAY 2012 | DEV Track | Session 8 - Getting Dimension with Data by C.Tecta...
Maintenance_Plans_Zupełnie_Znienacka
Kompletny przewodnik po SQL injection dla developerów PHP (i nie tylko)
Śniadanie Daje Moc
Ad

More from Polish SQL Server User Group (8)

PDF
SQLDay2013_MarcinSzeliga_DataInDataMining
PDF
26th_Meetup_of_PLSSUG-ColumnStore_Indexes_byBeataZalewa_session
PDF
SQLDay2011_Sesja03_Fakty,MiaryISwiatRealny_GrzegorzStolecki
PDF
SQLDay2011_Sesja01_ModelowanieIZasilanieWymiarówHurtowniDanych_ŁukaszGrala
PDF
SQLDay2011_Sesja05_MicrosoftSQLServerExecutionPlansFromCompilationToCachingTo...
PDF
How to tune a database application without changing a single query - Maciej P...
PDF
Co nowego w SQL Server 11 – Denali CTP1 - Grzegorz Stolecki, Łukasz Grala i K...
PDF
Master Data Services – Po co nam kolejna usługa w Sql Server - Mariusz Koprowski
SQLDay2013_MarcinSzeliga_DataInDataMining
26th_Meetup_of_PLSSUG-ColumnStore_Indexes_byBeataZalewa_session
SQLDay2011_Sesja03_Fakty,MiaryISwiatRealny_GrzegorzStolecki
SQLDay2011_Sesja01_ModelowanieIZasilanieWymiarówHurtowniDanych_ŁukaszGrala
SQLDay2011_Sesja05_MicrosoftSQLServerExecutionPlansFromCompilationToCachingTo...
How to tune a database application without changing a single query - Maciej P...
Co nowego w SQL Server 11 – Denali CTP1 - Grzegorz Stolecki, Łukasz Grala i K...
Master Data Services – Po co nam kolejna usługa w Sql Server - Mariusz Koprowski
Ad

26th_Meetup_of_PLSSUG_WROCLAW-ColumnStore_Indexes_byBeataZalewa_scripts

  • 1. 1. TworzenieColumnStore.sql -- to ćwiczenie możemy wykonać w kontekście dowolnej bazy danych, tutaj AdventureWorks2012 USE AdventureWorks2012 GO --stworzenie tabeli CREATETABLE dbo.ColumnStoreIndex( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2) ) -- Stworzenie indeksu klastrowego CREATECLUSTEREDINDEX IX_Column1 ON dbo.ColumnStoreIndex(Column1) -- stworzenie indeksu nieklastrowego COLUMNSTORE CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4 ON dbo.ColumnStoreIndex(Column2,Column3,Column4) --czyszczenie bazy danych DROPINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStoreIndex GO DROPTABLE dbo.ColumnStoreIndex GO 2. UpdateTabeli.sql USE AdventureWorks2012 GO --stworzenie tabeli CREATETABLE dbo.ColumnStore( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2) ) -- stworzenie indeksu klastrowego CREATECLUSTEREDINDEX IX_Column1 ON dbo.ColumnStore(Column1) -- stworzenie indeksu nieklastrowego COLUMNSTORE CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4 ON 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ę INSERT ALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore DISABLE; --wstawienie rekordu INSERTINTO dbo.ColumnStore VALUES('Col2 Val1',GETDATE(),10.23)
  • 2. INSERTINTO dbo.ColumnStore VALUES('Col2 Val2',GETDATE(),10.24) -- przebudowa indeksu columnstore co wykonaniu instrukcji INSERT ALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore REBUILD; --czyszczenie bazy danych DROPINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore GO DROPTABLE dbo.ColumnStore GO --------------- --Alternatywnie my możemy najpierw stworzyć tabelę, potem dodać rekord i potem dopiero stworzyć indeks columnstore --stworzenie tabeli CREATETABLE dbo.ColumnStore1( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2) ) --Wstawienie rekordu INSERTINTO dbo.ColumnStore1 VALUES('Col2 Val1',GETDATE(),10.23) INSERTINTO dbo.ColumnStore1 VALUES('Col2 Val2',GETDATE(),10.24) --stworzenie indeksów -- stworzenie indeksu klastrowego CREATECLUSTEREDINDEX IX_Column1 ON dbo.ColumnStore1(Column1) -- stworzenie indeksu nieklastrowego COLUMNSTORE CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore1(Column2,Column3,Column4) --ten sposób zadziała tylko za pierwszym razem (wykonanie insertów przed stworzeniem indeksu columnstore). --próba wykonania tej instrukcji, spowoduje wyżwietlenie błędu UPDATE dbo.ColumnStore1 SET Column2 ='Updated Value' WHERE Column1 = 1 -- aby można wykonać tą aktualizację należy wyłączyć indeks columnstore zanim spróbujemy wykonać UPDATE ALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore1 DISABLE; UPDATE dbo.ColumnStore1 SET Column2 ='Updated Value' WHERE Column1 = 1 -- przebudowa indeksu columnstore jak wykona się instrukcja INSERT ALTERINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore1 REBUILD; SELECT*FROM dbo.ColumnStore1 -- Czyszczenie bazy danych DROPINDEX IX_CS_C2_C3_C4 ON dbo.ColumnStore1 GO DROPTABLE dbo.ColumnStore1 GO
  • 3. 3. Ograniczenia.sql --1. Nie można stworzyć klastrowego indeksu ColumnStore USE AdventureWorks2012 GO --stworzenie tabeli CREATETABLE dbo.ColumnStoreIndex( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2) ) -- próba stworzenia indeksu klastrowego COLUMNSTORE CREATECLUSTERED COLUMNSTORE INDEX IX_CS_C2_C3_C4 ON dbo.ColumnStoreIndex(Column2,Column3,Column4) -- Czyszczenie bazy danych DROPTABLE dbo.ColumnStoreIndex --2. Nie można stworzyć nieklastrowego indeksu COLUMNSTORE z opcją INCLUDE USE AdventureWorks2012 GO --stworzenie tabeli CREATETABLE dbo.ColumnStoreIndex( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2) ) -- próba stworzenia nieklastrowanego indeksu COLUMNSTORE CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2 ON dbo.ColumnStoreIndex(Column2) INCLUDE (Column1 ,Column3 ,Column4 ) GO -- Czyszczenie bazy danych DROPTABLE dbo.ColumnStoreIndex --3.Nie można stworzyć indeksu ColumnStore na kolumnach wyliczanych (computed) --stworzenie tabeli CREATETABLE dbo.ColumnStoreIndex( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 INT, Column5 AS (Column1+Column4)-- kolumna wyliczana )
  • 4. -- stworzenie nieklastrowego indeksu COLUMNSTORE CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2 ON dbo.ColumnStoreIndex(Column5) -- Czyszczenie bazy danych DROPTABLE dbo.ColumnStoreIndex --4. Nie można stworzyć wielu indeksów ColumnStore --stworzenie tabeli CREATETABLE dbo.ColumnStoreIndex( Column1 INTIDENTITY, Column2 VARCHAR(50), Column3 DATETIME, Column4 NUMERIC(16,2) ) -- Próba stworzenia kliku indeksów COLUMNSTORE CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C2 ON dbo.ColumnStoreIndex(Column2) CREATENONCLUSTERED COLUMNSTORE INDEX IX_CS_C3 ON dbo.ColumnStoreIndex(Column3) -- Czyszczenie bazy danych DROPTABLE dbo.ColumnStoreIndex 4. TestWydajności.sql USE AdventureWorks2012 GO -- stworzenie nowej tabeli CREATETABLE 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 klastrowego CREATECLUSTEREDINDEX CL_TestColumnStoreIndexes ON dbo.TestColumnStoreIndexes ( [SalesOrderDetailID]) GO -- stworzenie tabeli do testów -- To zapytanie może się wykonywać dożć długo
  • 5. INSERTINTO dbo.TestColumnStoreIndexes SELECT S1.* FROM Sales.SalesOrderDetail S1 GO 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łych indeksów. -- należy zanotować użycie operacji IO w zapytaniu -- potem sprawdzimy to samo przy użyciu indeksów ColumnStore i znowu zmierzenie operacji IO -- Test wydajnożci -- Porównanie zwykłego indeksu z indeksem ColumnStore USE AdventureWorks2012 GO SETSTATISTICSIOON GO --włączenie Actual Execution Plan -- Select na tabeli ze zwykłym indeksem nieklastrowym SELECT ProductID,SUM(UnitPrice) SumUnitPrice,AVG(UnitPrice) AvgUnitPrice, SUM(OrderQty) SumOrderQty,AVG(OrderQty) AvgOrderQty FROM dbo.TestColumnStoreIndexes GROUPBY ProductID ORDERBY ProductID GO --Table 'dbo.TestColumnStoreIndexes'. Scan count 1, logical reads 345590, physical reads 0, read-ahead reads 0. --stworzenie indeksu ColumnStore CREATENONCLUSTERED COLUMNSTORE INDEX IX_TestColumnStoreIndexes ON TestColumnStoreIndexes (UnitPrice, OrderQty, ProductID) GO -- Select na tabeli z indeksem Columnstore SELECT ProductID,SUM(UnitPrice) SumUnitPrice,AVG(UnitPrice) AvgUnitPrice, SUM(OrderQty) SumOrderQty,AVG(OrderQty) AvgOrderQty FROM [dbo].TestColumnStoreIndexes GROUPBY ProductID ORDERBY ProductID GO -- wydajność radykalnie wzrosła po stworzeniu indeksu ColumnStore Index. -- Ilożć stron, które zapytanie miało odczytać została drastycznie zredukowana --jako że kolumny, które są potrzebne do zapytania są przechowywane na tej samej 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 danych DROPINDEX [IX_TestColumnStoreIndexes] ON dbo.TestColumnStoreIndexes GO TRUNCATETABLE dbo.TestColumnStoreIndexes
  • 6. GO DROPTABLE dbo.TestColumnStoreIndexes GO 5. BatchExecutionMode.sql USE AdventureWorks2012; GO --stworzenie funkcji partycjonującej CREATEPARTITIONFUNCTION [ByOrderDateMonthPF](int)ASRANGERIGHT FORVALUES ( 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ącego CREATEPARTITION SCHEME [ByOrderDateMonthRange] ASPARTITION [ByOrderDateMonthPF] ALLTO ([PRIMARY]) GO -- stworzenie partycjonującej wersji tabeli FactResellerSales CREATETABLE [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. [OrderDate] datetimeNULL, [DueDate] datetimeNULL, [ShipDate] datetimeNULL )ON ByOrderDateMonthRange(OrderDateKey); GO -- skopiowanie danych z tabeli FactResellerSales do nowej tabeli INSERTINTO dbo.FactResellerSalesPtnd WITH(TABLOCK) SELECT*FROM AdventureWorksDW2012.dbo.FactResellerSales; GO -- stworzenie indeksu columnstore CREATENONCLUSTERED 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 SalesByTerritory FROM FactResellerSalesPtnd GROUPBY SalesTerritoryKey; --możemy zauważyć, że actual i estimated execution mode jest Row (linie 3 i 4 na liżcie Properties indeksu). --Row execution mode został wybrany ponieważ tabela nie jest wystarczająco duża, aby wywołać batch execution mode. --możemy użyć nieudokumentowanych opcji ROWCOUNT (dla 10 mln wierszy) i PAGECOUNT (dla 1 mln stron) do instrukcji UPDATE STATISTICS, --aby zasymulować, jakby się to wykonało na większej tabeli UPDATESTATISTICS FactResellerSalesPtnd WITHROWCOUNT= 10000000,PAGECOUNT= 1000000 --usunięcie z cache'u starego planu wykonania
  • 8. DBCC FREEPROCCACHE --wykonanie jeszcze raz tego zapytania SELECT SalesTerritoryKey,SUM(ExtendedAmount)AS SalesByTerritory FROM FactResellerSalesPtnd GROUPBY SalesTerritoryKey; --tym razem we włażciwożciach Columnstore Index Scan możemy zobaczyć, że wykonał to używać the batch execution mode --możemy także użyć nowego hinta IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX do wyłaczenia użycia indeksu columnstore. SELECT SalesTerritoryKey,SUM(ExtendedAmount)AS SalesByTerritory FROM FactResellerSalesPtnd GROUPBY SalesTerritoryKey OPTION (IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX); -- teraz plan wykonania pokazuje Nam skan tabeli FactResellerSalesPtnd, bez użycia indeksu columnstore. -- usunięcie tabeli DROPTABLE FactResellerSalesPtnd GO DROPPARTITION SCHEME ByOrderDateMonthRange GO DROPPARTITIONFUNCTION ByOrderDateMonthPF GO