sql >> Databasteknik >  >> RDS >> Sqlserver

MS SQL Server på Linux vs Windows Performance Test för att upptäcka skillnaden

Sedan lanseringen av SQL Server 2017 för Linux har Microsoft i stort sett förändrat hela spelet. Det möjliggjorde en helt ny värld av möjligheter för deras berömda relationsdatabas, och erbjöd det som bara var tillgängligt i Windows-utrymmet fram till dess.

Jag vet att en puristisk DBA omedelbart skulle berätta för mig att den färdiga SQL Server 2019 Linux-versionen har flera skillnader, när det gäller funktioner, när det gäller dess Windows-motsvarighet, till exempel:

  • Ingen SQL Server Agent
  • Ingen FileStream
  • Inga systemutvidgade lagrade procedurer (t.ex. xp_cmdshell)

Men jag blev nyfiken nog att tänka "tänk om de kan jämföras, åtminstone till viss del, med saker som båda kan göra?" Så jag tryckte på avtryckaren på ett par virtuella datorer, förberedde några enkla tester och samlade in data att presentera för dig. Låt oss se hur det blir!

Inledande överväganden

Här är specifikationerna för varje virtuell dator:

  • Windows
    • Windows 10 OS
    • 4 vCPU:er
    • 4 GB RAM
    • 30 GB SSD
  • Linux
    • Ubuntu Server 20.04 LTS
    • 4 vCPU:er
    • 4 GB RAM
    • 30 GB SSD

För SQL Server-versionen valde jag den allra senaste för båda operativsystemen:SQL Server 2019 Developer Edition CU10

I varje distribution var det enda som aktiverades Instant File Initialization (aktiverad som standard på Linux, aktiverad manuellt på Windows). Utöver det fanns standardvärdena kvar för resten av inställningarna.

  • I Windows kan du välja att aktivera omedelbar filinitiering med installationsguiden.

Det här inlägget kommer inte att täcka specificiteten för Instant File Initialization-arbetet i Linux. Jag lämnar dock en länk till den dedikerade artikeln som du kan läsa senare (observera att det blir lite tungt på den tekniska sidan).

Vad innehåller testet?

  1. I varje SQL Server 2019-instans distribuerade jag en testdatabas och skapade en tabell med bara ett fält (ett NVARCHAR(MAX)).
  2. Med en slumpmässigt genererad sträng på 1 000 000 tecken utförde jag följande steg:
    • *Infoga X antal rader i testtabellen.
    • Mät hur lång tid det tog att slutföra INSERT-satsen.
    • Mät storleken på MDF- och LDF-filerna.
    • Ta bort alla rader i testtabellen.
    • **Mät hur lång tid det tog att slutföra DELETE-satsen.
    • Mät storleken på LDF-filen.
    • Släpp testdatabasen.
    • Skapa testdatabasen igen.
    • Upprepa samma cykel.

*X utfördes för 1 000, 5 000, 10 000, 25 000 och 50 000 rader.

**Jag vet att en TRUNCATE-sats gör jobbet mycket mer effektivt, men min poäng här är att bevisa hur väl varje transaktionslogg hanteras för borttagningsoperationen i varje operativsystem.

Du kan fortsätta till webbplatsen jag använde för att generera den slumpmässiga strängen om du vill gräva djupare.

Här är avsnitten av TSQL-koden som jag använde för tester i varje operativsystem:

Linux TSQL-koder

Skapa databas och tabell

DROP DATABASE IF EXISTS test
CREATE DATABASE test
    ON
(FILENAME= '/var/opt/mssql/data/test.mdf', NAME = test, FILEGROWTH = 128MB)
LOG ON
(FILENAME= '/var/opt/mssql/data/test_log.ldf',NAME = test_log, FILEGROWTH = 64MB);

CREATE TABLE test.dbo.ubuntu(
    long_string NVARCHAR(MAX) NOT NULL
)

Storleken på MDF- och LDF-filerna för testdatabasen

SELECT 
        DB_NAME(database_id) AS 'DB',
        type_desc AS 'Type',
        state_desc AS 'State',
        CONVERT(DECIMAL(10,2),size*8/1024) AS 'Size',
        CONVERT(DECIMAL(10,2),growth*8/1024) AS 'Growth'
FROM    sys.master_files
WHERE   DB_NAME(database_id) = 'test'

Skärmbilden nedan visar storleken på datafilerna när ingenting är lagrat i databasen:

Frågor för att avgöra om Instant File Initialization är aktiverat

SELECT 
       servicename,
       instant_file_initialization_enabled
FROM   sys.dm_server_services
WHERE  servicename = 'SQL Server (MSSQLSERVER)'

Windows TSQL-koder

Skapa databas och tabell

DROP DATABASE IF EXISTS test
CREATE DATABASE test
    ON
(FILENAME= 'S:\Program Files\Microsoft SQL Server\MSSQL15.WINDOWS\MSSQL\DATA\test.mdf', NAME = test, FILEGROWTH = 128MB)
LOG ON
(FILENAME= ''S:\Program Files\Microsoft SQL Server\MSSQL15.WINDOWS\MSSQL\DATA\test_log.ldf',NAME = test_log, FILEGROWTH = 64MB);

CREATE TABLE test.dbo.windows(
    long_string NVARCHAR(MAX) NOT NULL
)

Storleken på MDF- och LDF-filerna för testdatabasen

SELECT 
        DB_NAME(database_id) AS 'DB',
        type_desc AS 'Type',
        state_desc AS 'State',
        CONVERT(DECIMAL(10,2),size*8/1024) AS 'Size',
        CONVERT(DECIMAL(10,2),growth*8/1024) AS 'Growth'
FROM    sys.master_files
WHERE   DB_NAME(database_id) = 'test'

Följande skärmdump visar storleken på datafilerna när ingenting är lagrat i databasen:

Fråga för att avgöra om Instant File Initialization är aktiverat

SELECT 
       servicename,
       instant_file_initialization_enabled
FROM   sys.dm_server_services
WHERE  servicename = 'SQL Server (MSSQLSERVER)'

Skript för att utföra INSERT-satsen:

@limit -> här specificerade jag antalet rader som skulle infogas i testtabellen

För Linux, eftersom jag körde skriptet med SQLCMD, satte jag DATEDIFF-funktionen i slutet. Den låter mig veta hur många sekunder hela exekveringen tar (för Windows-varianten kunde jag helt enkelt ha tagit en glimt av timern i SQL Server Management Studio).

Hela strängen på 1 000 000 tecken går istället för "XXXX". Jag uttrycker det så bara för att presentera det snyggt i det här inlägget.

SET NOCOUNT ON
GO
DECLARE @StartTime DATETIME;
DECLARE @i INT;
DECLARE @limit INT;
SET @StartTime = GETDATE();
SET @i = 0;
SET @limit = 1000;

WHILE(@i < @limit)
BEGIN
	INSERT INTO test.dbo.ubuntu VALUES('XXXX');
	SET @i = @i + 1
END

SELECT DATEDIFF(SECOND,@StartTime,GETDATE()) AS 'Elapsed Seconds';

Skript för att utföra DELETE-satsen

SET NOCOUNT ON
GO
DECLARE @StartTime DATETIME;
SET @StartTime = GETDATE();

DELETE FROM test.dbo.ubuntu;

SELECT DATEDIFF(SECOND,@StartTime,GETDATE()) AS 'Elapsed Seconds';

Erhållna resultat

Alla storlekar uttrycks i MB. Alla tidsmätningar uttrycks i sekunder.

INSERT tid 1 000 poster 5 000 poster 10 000 poster 25 000 poster 50 000 poster
Linux 4 23 43 104 212
Windows 4 28 172 531 186
Storlek (MDF) 1 000 poster 5 000 poster 10 000 poster 25 000 poster 50 000 poster
Linux 264 1032 2056 5128 10184
Windows 264 1032 2056 5128 10248
Storlek (LDF) 1 000 poster 5 000 poster 10 000 poster 25 000 poster 50 000 poster
Linux 104 264 360 552 148
Windows 136 328 392 456 584
RADERA tid 1 000 poster 5 000 poster 10 000 poster 25 000 poster 50 000 poster
Linux 1 1 74 215 469
Windows 1 63 126 357 396
DELETE Size (LDF) 1 000 poster 5 000 poster 10 000 poster 25 000 poster 50 000 poster
Linux 136 264 392 584 680
Windows 200 328 392 456 712

Nyckelinsikter

  • Storleken på MDF:n var ganska konsekvent över hela testet, varierade något i slutet (men inget för tokigt).
  • Timingen för INSERT var bättre i Linux för det mesta, förutom i slutet när Windows "vann omgången".
  • Storleken på transaktionsloggfilen hanterades bättre i Linux efter varje omgång INSERT.
  • Timingen för DELETEs var bättre i Linux för det mesta, förutom i slutet där Windows "vann omgången" (jag tycker att det är konstigt att Windows också vann den sista INSERT-omgången).
  • Storleken på transaktionsloggfilerna efter varje omgång av DELETEs var i stort sett oavgjort när det gäller upp- och nedgångar mellan de två.
  • Jag skulle ha velat testa med 100 000 rader, men jag hade lite ont om diskutrymme, så jag begränsade det till 50 000.

Slutsats

Baserat på resultaten från detta test, skulle jag säga att det inte finns någon stark anledning att hävda att Linux-varianten presterar exponentiellt bättre än sin Windows-motsvarighet. Detta är naturligtvis inte på något sätt ett formellt test som du kan grunda på för att fatta ett sådant beslut. Men själva övningen var intressant nog för mig.

Jag skulle gissa att SQL Server 2019 för Windows ibland hamnar lite efter (inte mycket) på grund av GUI-renderingen i bakgrunden, vilket inte händer på Ubuntu Server-sidan av stängslet.

Om du förlitar dig starkt på funktioner och möjligheter som är exklusiva för Windows (åtminstone när detta skrivs), så kör för all del. Annars kommer du knappast att göra ett dåligt val genom att gå för det ena framför det andra.


  1. Så här klusterar du dina ProxySQL-lastbalanserare

  2. Hur uppgraderar jag PostgreSQL från version 9.6 till version 10.1 utan att förlora data?

  3. En fastighetsbyrådatamodell

  4. Göra beräkningar i MySQL vs PHP