Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Leistungstest für MS SQL Server unter Linux im Vergleich zu Windows, um den Unterschied zu erkennen

Seit der Veröffentlichung von SQL Server 2017 für Linux hat Microsoft so ziemlich das gesamte Spiel verändert. Es eröffnete eine ganze Welt neuer Möglichkeiten für ihre berühmte relationale Datenbank und bot das, was bis dahin nur im Windows-Bereich verfügbar war.

Ich weiß, dass ein puristischer DBA mir sofort sagen würde, dass die sofort einsatzbereite Linux-Version von SQL Server 2019 in Bezug auf die Funktionen einige Unterschiede zu ihrem Windows-Pendant aufweist, wie zum Beispiel:

  • Kein SQL Server-Agent
  • Kein FileStream
  • Keine erweiterten gespeicherten Systemprozeduren (z. B. xp_cmdshell)

Ich wurde jedoch neugierig genug, um zu denken:„Was wäre, wenn sie zumindest bis zu einem gewissen Grad mit Dingen verglichen werden könnten, die beide tun können?“ Also habe ich den Auslöser für ein paar VMs gedrückt, einige einfache Tests vorbereitet und Daten gesammelt, um sie Ihnen zu präsentieren. Mal sehen, wie sich die Dinge entwickeln!

Erste Überlegungen

Hier sind die Spezifikationen jeder VM:

  • Windows
    • Windows 10-Betriebssystem
    • 4 vCPUs
    • 4 GB Arbeitsspeicher
    • 30-GB-SSD
  • Linux
    • Ubuntu Server 20.04 LTS
    • 4 vCPUs
    • 4 GB Arbeitsspeicher
    • 30-GB-SSD

Für die SQL Server-Version habe ich die allerneueste Version für beide Betriebssysteme ausgewählt:SQL Server 2019 Developer Edition CU10

In jeder Bereitstellung war nur die sofortige Dateiinitialisierung aktiviert (standardmäßig aktiviert unter Linux, manuell aktiviert unter Windows). Ansonsten blieben die Standardwerte für die restlichen Einstellungen erhalten.

  • Unter Windows können Sie die sofortige Dateiinitialisierung mit dem Installationsassistenten aktivieren.

Dieser Beitrag behandelt nicht die Besonderheiten der Instant File Initialization-Arbeit in Linux. Ich hinterlasse Ihnen jedoch einen Link zu dem speziellen Artikel, den Sie später lesen können (beachten Sie, dass es auf der technischen Seite etwas schwer wird).

Was beinhaltet der Test?

  1. In jeder SQL Server 2019-Instanz habe ich eine Testdatenbank bereitgestellt und eine Tabelle mit nur einem Feld erstellt (ein NVARCHAR(MAX)).
  2. Mit einer zufällig generierten Zeichenfolge von 1.000.000 Zeichen habe ich die folgenden Schritte ausgeführt:
    • *Fügen Sie eine Anzahl von X Zeilen in die Testtabelle ein.
    • Messen Sie, wie viel Zeit es gedauert hat, die INSERT-Anweisung abzuschließen.
    • Messen Sie die Größe der MDF- und LDF-Dateien.
    • Alle Zeilen in der Testtabelle löschen.
    • **Messen Sie, wie viel Zeit es gedauert hat, die DELETE-Anweisung abzuschließen.
    • Messen Sie die Größe der LDF-Datei.
    • Löschen Sie die Testdatenbank.
    • Erstellen Sie die Testdatenbank erneut.
    • Wiederholen Sie denselben Zyklus.

*X wurde für 1.000, 5.000, 10.000, 25.000 und 50.000 Zeilen durchgeführt.

**Ich weiß, dass eine TRUNCATE-Anweisung die Arbeit viel effizienter erledigt, aber hier möchte ich beweisen, wie gut jedes Transaktionsprotokoll für den Löschvorgang in jedem Betriebssystem verwaltet wird.

Sie können zu der Website weitergehen, die ich verwendet habe, um die Zufallszeichenfolge zu generieren, wenn Sie tiefer graben möchten.

Hier sind die Abschnitte des TSQL-Codes, den ich für Tests in jedem Betriebssystem verwendet habe:

Linux TSQL-Codes

Datenbank- und Tabellenerstellung

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
)

Größe der MDF- und LDF-Dateien für die Testdatenbank

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'

Der folgende Screenshot zeigt die Größe der Datendateien, wenn nichts in der Datenbank gespeichert ist:

Abfragen, um festzustellen, ob die sofortige Dateiinitialisierung aktiviert ist

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

Windows TSQL-Codes

Datenbank- und Tabellenerstellung

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
)

Größe der MDF- und LDF-Dateien für die Testdatenbank

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'

Der folgende Screenshot zeigt die Größe der Datendateien, wenn nichts in der Datenbank gespeichert ist:

Abfrage, ob Instant File Initialization aktiviert ist

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

Skript zum Ausführen der INSERT-Anweisung:

@limit -> hier habe ich die Anzahl der Zeilen angegeben, die in die Testtabelle eingefügt werden sollen

Da ich das Skript unter Linux mit SQLCMD ausgeführt habe, habe ich die DATEDIFF-Funktion ganz am Ende eingefügt. Es lässt mich wissen, wie viele Sekunden die gesamte Ausführung dauert (für die Windows-Variante hätte ich einfach einen Blick auf den Timer in SQL Server Management Studio werfen können).

Die ganze Zeichenfolge von 1.000.000 Zeichen wird anstelle von „XXXX“ angezeigt. Ich sage es nur so, um es in diesem Beitrag schön darzustellen.

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 zum Ausführen der DELETE-Anweisung

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

DELETE FROM test.dbo.ubuntu;

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

Die erzielten Ergebnisse

Alle Größen werden in MB ausgedrückt. Alle Zeitmessungen werden in Sekunden ausgedrückt.

ZEIT EINFÜGEN 1.000 Datensätze 5.000 Datensätze 10.000 Datensätze 25.000 Datensätze 50.000 Datensätze
Linux 4 23 43 104 212
Windows 4 28 172 531 186
Größe (MDF) 1.000 Datensätze 5.000 Datensätze 10.000 Datensätze 25.000 Datensätze 50.000 Datensätze
Linux 264 1032 2056 5128 10184
Windows 264 1032 2056 5128 10248
Größe (LDF) 1.000 Datensätze 5.000 Datensätze 10.000 Datensätze 25.000 Datensätze 50.000 Datensätze
Linux 104 264 360 552 148
Windows 136 328 392 456 584
Zeit löschen 1.000 Datensätze 5.000 Datensätze 10.000 Datensätze 25.000 Datensätze 50.000 Datensätze
Linux 1 1 74 215 469
Windows 1 63 126 357 396
Größe LÖSCHEN (LDF) 1.000 Datensätze 5.000 Datensätze 10.000 Datensätze 25.000 Datensätze 50.000 Datensätze
Linux 136 264 392 584 680
Windows 200 328 392 456 712

Wichtige Erkenntnisse

  • Die Größe des MDF war während des gesamten Tests ziemlich konstant und variierte am Ende leicht (aber nicht zu verrückt).
  • Die Timings für INSERTs waren unter Linux größtenteils besser, außer ganz am Ende, als Windows „die Runde gewann“.
  • Die Größe der Transaktionsprotokolldatei wurde unter Linux nach jeder Runde von INSERTs besser gehandhabt.
  • Die Timings für DELETEs waren unter Linux größtenteils besser, außer ganz am Ende, wo Windows „die Runde gewann“ (ich finde es merkwürdig, dass Windows auch die letzte INSERT-Runde gewann).
  • Die Größe der Transaktionsprotokolldateien nach jeder DELETE-Runde war in Bezug auf Höhen und Tiefen zwischen den beiden ziemlich gleich.
  • Ich hätte gerne mit 100.000 Zeilen getestet, aber mir fehlte etwas Speicherplatz, also habe ich es auf 50.000 begrenzt.

Schlussfolgerung

Basierend auf den Ergebnissen dieses Tests würde ich sagen, dass es keinen triftigen Grund gibt zu behaupten, dass die Linux-Variante exponentiell besser abschneidet als ihr Windows-Pendant. Natürlich ist dies keineswegs ein formaler Test, auf den Sie sich stützen können, um eine solche Entscheidung zu treffen. Die Übung selbst war jedoch interessant genug für mich.

Ich würde vermuten, dass SQL Server 2019 für Windows aufgrund des GUI-Renderings im Hintergrund manchmal etwas (nicht viel) hinterherhinkt, was auf der Ubuntu-Server-Seite des Zauns nicht passiert.

Wenn Sie sich stark auf Funktionen und Fähigkeiten verlassen, die exklusiv für Windows sind (zumindest zum Zeitpunkt des Schreibens dieses Artikels), dann entscheiden Sie sich auf jeden Fall dafür. Andernfalls werden Sie kaum eine schlechte Wahl treffen, wenn Sie sich für eines entscheiden.