Dal rilascio di SQL Server 2017 per Linux, Microsoft ha praticamente cambiato l'intero gioco. Ha consentito un intero nuovo mondo di possibilità per il loro famoso database relazionale, offrendo ciò che fino ad allora era disponibile solo nello spazio Windows.
So che un DBA purista mi direbbe subito che la versione Linux di SQL Server 2019 pronta all'uso presenta diverse differenze, in termini di funzionalità, rispetto alla sua controparte Windows, come ad esempio:
- Nessun agente SQL Server
- Nessun FileStream
- Nessuna stored procedure estesa di sistema (ad es. xp_cmdshell)
Tuttavia, sono diventato abbastanza curioso da pensare "e se potessero essere confrontati, almeno in una certa misura, con cose che entrambi possono fare?" Quindi, ho premuto il grilletto su un paio di macchine virtuali, ho preparato alcuni semplici test e raccolto i dati da presentarvi. Vediamo come vanno le cose!
Considerazioni iniziali
Ecco le specifiche di ciascuna VM:
- Finestre
- Sistema operativo Windows 10
- 4 vCPU
- 4 GB di RAM
- SSD da 30 GB
- Linux
- Ubuntu Server 20.04 LTS
- 4 vCPU
- 4 GB di RAM
- SSD da 30 GB
Per la versione di SQL Server, ho scelto l'ultima versione per entrambi i sistemi operativi:SQL Server 2019 Developer Edition CU10
In ogni distribuzione, l'unica cosa abilitata era l'inizializzazione file istantanea (abilitata per impostazione predefinita su Linux, abilitata manualmente su Windows). A parte questo, i valori predefiniti sono rimasti per il resto delle impostazioni.
- In Windows, puoi scegliere di abilitare l'inizializzazione file istantanea con la procedura guidata di installazione.
Questo post non tratterà la specificità del lavoro di inizializzazione file istantanea in Linux. Vi lascio comunque un link all'articolo dedicato che potrete leggere più avanti (notate che dal punto di vista tecnico diventa un po' pesante).
Cosa include il test?
- In ogni istanza di SQL Server 2019, ho distribuito un database di test e creato una tabella con un solo campo (un NVARCHAR(MAX)).
- Utilizzando una stringa generata casualmente di 1.000.000 di caratteri, ho eseguito i seguenti passaggi:
- *Inserisci X numero di righe nella tabella di test.
- Misura il tempo impiegato per completare l'istruzione INSERT.
- Misura la dimensione dei file MDF e LDF.
- Elimina tutte le righe nella tabella di test.
- **Misura il tempo impiegato per completare l'istruzione DELETE.
- Misura la dimensione del file LDF.
- Elimina il database di prova.
- Crea di nuovo il database di prova.
- Ripeti lo stesso ciclo.
*X è stato eseguito per 1.000, 5.000, 10.000, 25.000 e 50.000 righe.
**So che un'istruzione TRUNCATE svolge il lavoro in modo più efficiente, ma il mio punto qui è dimostrare quanto ogni log delle transazioni sia gestito per l'operazione di eliminazione in ciascun sistema operativo.
Puoi procedere al sito Web che ho usato per generare la stringa casuale se vuoi scavare più a fondo.
Ecco le sezioni del codice TSQL che ho usato per i test in ciascun sistema operativo:
Codici Linux TSQL
Creazione database e tabelle
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
)
Dimensioni dei file MDF e LDF per il database di test
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'
Lo screenshot seguente mostra le dimensioni dei file di dati quando non è archiviato nulla nel database:
Query per determinare se l'inizializzazione file istantanea è abilitata
SELECT
servicename,
instant_file_initialization_enabled
FROM sys.dm_server_services
WHERE servicename = 'SQL Server (MSSQLSERVER)'
Codici TSQL di Windows
Creazione database e tabelle
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
)
Dimensioni dei file MDF e LDF per il database di test
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'
La schermata seguente mostra le dimensioni dei file di dati quando non è archiviato nulla nel database:
Query per determinare se l'inizializzazione file istantanea è abilitata
SELECT
servicename,
instant_file_initialization_enabled
FROM sys.dm_server_services
WHERE servicename = 'SQL Server (MSSQLSERVER)'
Script per eseguire l'istruzione INSERT:
@limit -> qui ho specificato il numero di righe da inserire nella tabella di test
Per Linux, poiché ho eseguito lo script utilizzando SQLCMD, ho inserito la funzione DATEDIFF proprio alla fine. Mi fa sapere quanti secondi impiega l'intera esecuzione (per la variante Windows, avrei potuto semplicemente dare un'occhiata al timer in SQL Server Management Studio).
L'intera stringa di 1.000.000 di caratteri va invece di "XXXX". Lo metto così solo per presentarlo bene in questo post.
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';
Script per eseguire l'istruzione DELETE
SET NOCOUNT ON
GO
DECLARE @StartTime DATETIME;
SET @StartTime = GETDATE();
DELETE FROM test.dbo.ubuntu;
SELECT DATEDIFF(SECOND,@StartTime,GETDATE()) AS 'Elapsed Seconds';
I risultati ottenuti
Tutte le dimensioni sono espresse in MB. Tutte le misurazioni del tempo sono espresse in secondi.
INSERIRE ora | 1000 record | 5.000 record | 10.000 record | 25.000 record | 50.000 record |
Linux | 4 | 23 | 43 | 104 | 212 |
Finestre | 4 | 28 | 172 | 531 | 186 |
Dimensioni (MDF) | 1000 record | 5.000 record | 10.000 record | 25.000 record | 50.000 record |
Linux | 264 | 1032 | 2056 | 5128 | 10184 |
Finestre | 264 | 1032 | 2056 | 5128 | 10248 |
Taglia (LDF) | 1000 record | 5.000 record | 10.000 record | 25.000 record | 50.000 record |
Linux | 104 | 264 | 360 | 552 | 148 |
Finestre | 136 | 328 | 392 | 456 | 584 |
ELIMINA Ora | 1000 record | 5.000 record | 10.000 record | 25.000 record | 50.000 record |
Linux | 1 | 1 | 74 | 215 | 469 |
Finestre | 1 | 63 | 126 | 357 | 396 |
ELIMINA Dimensione (LDF) | 1000 record | 5.000 record | 10.000 record | 25.000 record | 50.000 record |
Linux | 136 | 264 | 392 | 584 | 680 |
Finestre | 200 | 328 | 392 | 456 | 712 |
Informazioni chiave
- La dimensione dell'MDF è stata pressoché costante durante l'intero test, variando leggermente alla fine (ma niente di troppo folle).
- I tempi per gli INSERT erano migliori in Linux per la maggior parte, tranne che alla fine quando Windows "ha vinto il round".
- La dimensione del file di registro delle transazioni è stata gestita meglio in Linux dopo ogni round di INSERT.
- I tempi per DELETE erano migliori in Linux per la maggior parte, tranne la fine dove Windows "ha vinto il round" (trovo curioso che Windows abbia vinto anche il round INSERT finale).
- La dimensione dei file di registro delle transazioni dopo ogni round di DELETE era praticamente un pareggio in termini di alti e bassi tra i due.
- Mi sarebbe piaciuto eseguire il test con 100.000 righe, ma lo spazio su disco era un po' corto, quindi l'ho limitato a 50.000.
Conclusione
Sulla base dei risultati ottenuti da questo test, direi che non ci sono validi motivi per affermare che la variante Linux abbia prestazioni esponenzialmente migliori rispetto alla sua controparte Windows. Naturalmente, questo non è affatto un test formale su cui puoi basarti per prendere una decisione del genere. Tuttavia, l'esercizio in sé era abbastanza interessante per me.
Immagino che SQL Server 2019 per Windows a volte sia un po' indietro (non di molto) a causa del rendering della GUI in background, che non sta accadendo sul lato Ubuntu Server della recinzione.
Se fai molto affidamento su funzionalità e capacità esclusive di Windows (almeno al momento in cui scrivo), allora provaci. Altrimenti, difficilmente farai una scelta sbagliata scegliendo l'uno piuttosto che l'altro.