sql >> Databasteknik >  >> RDS >> Sqlserver

Utforska SQL Server 2014 SELECT INTO Parallelism

SQL Server 2014 CTP1 har varit ute i några veckor nu, och du har förmodligen sett en hel del press om minnesoptimerade tabeller och uppdateringsbara kolumnbutiksindex. Även om dessa verkligen är värda att uppmärksammas, ville jag i det här inlägget utforska den nya förbättringen SELECT ... INTO parallellism. Förbättringen är en av de färdiga att bära förändringar som, utifrån utseendet, inte kommer att kräva betydande kodändringar för att börja dra nytta av den. Mina utforskningar utfördes med version Microsoft SQL Server 2014 (CTP1) – 11.0.9120.5 (X64), Enterprise Evaluation Edition.

Parallell SELECT … INTO

SQL Server 2014 introducerar parallellaktiverad SELECT ... INTO för databaser och för att testa den här funktionen använde jag databasen AdventureWorksDW2012 och en version av tabellen FactInternetSales som hade 61 847 552 rader (jag var ansvarig för att lägga till dessa rader; de följer inte med databasen som standard).

Eftersom den här funktionen, från och med CTP1, kräver databaskompatibilitetsnivå 110, för teständamål ställde jag databasen till kompatibilitetsnivå 100 och körde följande fråga för mitt första test:

SELECT  [ProductKey],
        [OrderDateKey],
        [DueDateKey],
        [ShipDateKey],
        [CustomerKey],
        [PromotionKey],
        [CurrencyKey],
        [SalesTerritoryKey],
        [SalesOrderNumber],
        [SalesOrderLineNumber],
        [RevisionNumber],
        [OrderQuantity],
        [UnitPrice],
        [ExtendedAmount],
        [UnitPriceDiscountPct],
        [DiscountAmount],
        [ProductStandardCost],
        [TotalProductCost],
        [SalesAmount],
        [TaxAmt],
        [Freight],
        [CarrierTrackingNumber],
        [CustomerPONumber],
        [OrderDate],
        [DueDate],
        [ShipDate]
INTO dbo.FactInternetSales_V2
FROM dbo.FactInternetSales;

Frågekörningstiden var 3 minuter och 19 sekunder på min test-VM och den faktiska exekveringsplanen för frågekörning var följande:

SQL Server använde en serieplan, som jag förväntade mig. Lägg också märke till att min tabell hade ett icke-klustrat kolumnlagerindex på sig som skannades (jag skapade detta icke-klustrade kolumnlagerindex för användning med andra tester, men jag ska visa dig exekveringsplanen för klustrade kolumnbutiksindexförfrågningar senare också). Planen använde inte parallellism och Columnstore Index Scan använde radexekveringsläge istället för batchexekveringsläge.

Så härnäst ändrade jag databaskompatibilitetsnivån (och notera att det inte finns en SQL Server 2014-kompatibilitetsnivå i CTP1 ännu):

USE [master];
GO
ALTER DATABASE [AdventureWorksDW2012] SET COMPATIBILITY_LEVEL = 110;
GO

Jag tappade FactInternetSales_V2-tabellen och körde sedan om min ursprungliga SELECT ... INTO drift. Den här gången var frågans exekveringslängd 1 minut och 7 sekunder och den faktiska exekveringsplanen för frågan var som följer:

Vi har nu en parallell plan och den enda förändringen jag behövde göra var databaskompatibilitetsnivån för AdventureWorksDW2012. Min test-VM har fyra vCPU:er allokerade till den, och frågeexekveringsplanen fördelade rader över fyra trådar:

Den icke-klustrade Columnstore Index Scan, medan den använde parallellism, använde inte batchkörningsläge. Istället använde den radexekveringsläge.

Här är en tabell som visar testresultaten hittills:

Skanningstyp Kompatibilitetsnivå Parallell SELECT ... INTO Exekveringsläge Längd
Icke-klusterad kolumnbutiksindexsökning 100 Nej Rad 3:19
Icke-klusterad kolumnbutiksindexsökning 110 Ja Rad 1:07


Så som nästa test släppte jag det icke-klustrade kolumnlagerindexet och körde om SELECT ... INTO fråga med både databaskompatibilitetsnivå 100 och 110.

Kompatibilitetsnivå 100-testet tog 5 minuter och 44 sekunder att köra, och följande plan genererades:

Den seriella Clustered Index Scan tog 2 minuter och 25 sekunder längre än den seriella icke-klustrade Columnstore Index Scan.

Med kompatibilitetsnivå 110 tog frågan 1 minut och 55 sekunder att köra, och följande plan genererades:

I likhet med det parallella icke-klustrade Columnstore Index Scan-testet fördelade den parallella Clustered Index Scan rader över fyra trådar:

Följande tabell sammanfattar dessa två ovannämnda test:

Skanningstyp Kompatibilitetsnivå Parallell SELECT ... INTO Exekveringsläge Längd
Clustered Index Scan 100 Nej Rad (N/A) 5:44
Clustered Index Scan 110 Ja Rad (N/A) 1:55


Så då undrade jag över prestandan för ett klustrat kolumnbutiksindex (nytt i SQL Server 2014), så jag släppte de befintliga indexen och skapade ett klustrat kolumnbutiksindex på FactInternetSales-tabellen. Jag var också tvungen att släppa de åtta olika begränsningarna för främmande nyckel som definierats i tabellen innan jag kunde skapa det klustrade kolumnarkivet.

Diskussionen blir något akademisk eftersom jag jämför SELECT ... INTO prestanda på databaskompatibilitetsnivåer som inte erbjöd klustrade columnstore-index i första hand – inte heller gjorde de tidigare testerna för icke-klustrade columnstore-index på databaskompatibilitetsnivå 100 – och ändå är det intressant att se och jämföra de övergripande prestandaegenskaperna.

CREATE CLUSTERED COLUMNSTORE INDEX [CCSI_FactInternetSales] 
ON [dbo].[FactInternetSales] 
WITH (DROP_EXISTING = OFF);
GO

Dessutom tog operationen att skapa det klustrade kolumnbutiksindexet på en 61 847 552 miljoner radtabell 11 minuter och 25 sekunder med fyra tillgängliga vCPU:er (varav operationen utnyttjade dem alla), 4 GB RAM och virtuell gästlagring på OCZ Vertex SSD:er. Under den tiden var processorerna inte kopplade hela tiden, utan visade snarare toppar och dalar (ett urval av 60 sekunders CPU-aktivitet visas nedan):

Efter att det klustrade kolumnlagerindexet skapats körde jag om de två SELECT ... INTO tester. Kompatibilitetsnivå 100-testet tog 3 minuter och 22 sekunder att köra, och planen var seriell som förväntat (jag visar SQL Server Management Studio-versionen av planen sedan den klustrade Columnstore Index Scan, från och med SQL Server 2014 CTP1 , är ännu inte helt igenkänd av Plan Explorer):

Därefter ändrade jag databaskompatibilitetsnivån till 110 och körde testet igen, vilket den här gången tog 1 minut och 11 sekunder och hade följande faktiska exekveringsplan:

Planen fördelade rader över fyra trådar, och precis som det icke-klustrade kolumnlagerindexet var exekveringsläget för den klustrade Columnstore Index Scan rad och inte batch.

Följande tabell sammanfattar alla tester i detta inlägg (i varaktighetsordning, låg till hög):

Skanningstyp Kompatibilitetsnivå Parallell SELECT ... INTO Exekveringsläge Längd
Icke-klusterad kolumnbutiksindexsökning 110 Ja Rad 1:07
Clustered Columnstore Index Scan 110 Ja Rad 1:11
Clustered Index Scan 110 Ja Rad (N/A) 1:55
Icke-klusterad kolumnbutiksindexsökning 100 Nej Rad 3:19
Clustered Columnstore Index Scan 100 Nej Rad 3:22
Clustered Index Scan 100 Nej Rad (N/A) 5:44


Några observationer:

  • Jag är inte säker på om skillnaden mellan en parallell SELECT ... INTO operation mot ett icke-klustrat kolumnlagerindex kontra klustrat kolumnlagerindex är statistiskt signifikant. Jag skulle behöva göra fler tester, men jag tror att jag skulle vänta med att utföra dem tills RTM.
  • Jag kan lugnt säga att den parallella SELECT ... INTO överträffade de seriella ekvivalenterna avsevärt över ett klustrat index, ett icke-klusterat kolumnlager och ett klustrat kolumnlagerindextest.

Det är värt att nämna att dessa resultat är för en CTP-version av produkten, och mina tester bör ses som något som kan förändras i beteende av RTM – så jag var mindre intresserad av fristående varaktigheter jämfört med hur dessa varaktigheter jämförts mellan seriell och parallell villkor.

Vissa prestandafunktioner kräver betydande omfaktorer – men för SELECT ... INTO förbättring, allt jag behövde göra var att öka databaskompatibilitetsnivån för att börja se fördelarna, vilket definitivt är något jag uppskattar.


  1. Hur man visar ett datum i amerikanskt datumformat i SQL Server (T-SQL)

  2. 12 MySQL/MariaDB Säkerhet Best Practices för Linux

  3. Oracle 18c Ny funktion:Onlinemodifiering av partitionering

  4. Arkitektur och inställning av minne i PostgreSQL-databaser