Desde o lançamento do SQL Server 2017 para Linux, a Microsoft mudou praticamente todo o jogo. Permitiu um novo mundo de possibilidades para seu famoso banco de dados relacional, oferecendo o que estava disponível apenas no espaço Windows até então.
Eu sei que um DBA purista me diria imediatamente que a versão pronta para uso do SQL Server 2019 Linux tem várias diferenças, em termos de recursos, em relação à sua contraparte do Windows, como:
- Nenhum agente do SQL Server
- Sem FileStream
- Nenhum procedimento armazenado estendido do sistema (por exemplo, xp_cmdshell)
No entanto, fiquei curioso o suficiente para pensar “e se eles puderem ser comparados, pelo menos até certo ponto, com coisas que ambos podem fazer?” Então, eu puxei o gatilho em algumas VMs, preparei alguns testes simples e coletei dados para apresentar a você. Vamos ver como as coisas ficam!
Considerações iniciais
Aqui estão as especificações de cada VM:
- Janelas
- SO Windows 10
- 4 vCPUs
- 4 GB de RAM
- SSD de 30 GB
- Linux
- Servidor Ubuntu 20.04 LTS
- 4 vCPUs
- 4 GB de RAM
- SSD de 30 GB
Para a versão do SQL Server, escolhi o mais recente para ambos os sistemas operacionais:SQL Server 2019 Developer Edition CU10
Em cada implantação, a única coisa habilitada era a Inicialização Instantânea de Arquivo (habilitada por padrão no Linux, habilitada manualmente no Windows). Fora isso, os valores padrão permaneceram para o restante das configurações.
- No Windows, você pode optar por ativar a inicialização instantânea de arquivos com o assistente de instalação.
Esta postagem não abordará a especificidade do trabalho de inicialização instantânea de arquivos no Linux. No entanto, deixarei um link para o artigo dedicado que você pode ler mais tarde (observe que, pois fica um pouco pesado no lado técnico).
O que o teste inclui?
- Em cada instância do SQL Server 2019, implantei um banco de dados de teste e criei uma tabela com apenas um campo (um NVARCHAR(MAX)).
- Usando uma string gerada aleatoriamente de 1.000.000 caracteres, executei as seguintes etapas:
- *Insira um número X de linhas na tabela de teste.
- Meça quanto tempo levou para concluir a instrução INSERT.
- Meça o tamanho dos arquivos MDF e LDF.
- Exclua todas as linhas da tabela de teste.
- **Meça quanto tempo levou para concluir a instrução DELETE.
- Meça o tamanho do arquivo LDF.
- Retire o banco de dados de teste.
- Crie o banco de dados de teste novamente.
- Repita o mesmo ciclo.
*X foi realizado para 1.000, 5.000, 10.000, 25.000 e 50.000 linhas.
**Sei que uma instrução TRUNCATE faz o trabalho de maneira mais eficiente, mas meu objetivo aqui é provar quão bem cada log de transações é gerenciado para a operação de exclusão em cada sistema operacional.
Você pode prosseguir para o site que usei para gerar a string aleatória se quiser se aprofundar.
Aqui estão as seções do código TSQL que usei para testes em cada sistema operacional:
Códigos Linux TSQL
Criação de banco de dados e tabela
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
)
Tamanho dos arquivos MDF e LDF para o banco de dados de teste
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'
A captura de tela abaixo mostra os tamanhos dos arquivos de dados quando nada é armazenado no banco de dados:
Consultas para determinar se a inicialização instantânea de arquivos está ativada
SELECT
servicename,
instant_file_initialization_enabled
FROM sys.dm_server_services
WHERE servicename = 'SQL Server (MSSQLSERVER)'
Códigos TSQL do Windows
Criação de banco de dados e tabela
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
)
Tamanho dos arquivos MDF e LDF para o banco de dados de teste
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'
A captura de tela a seguir mostra os tamanhos dos arquivos de dados quando nada é armazenado no banco de dados:
Consulte para determinar se a inicialização instantânea de arquivos está ativada
SELECT
servicename,
instant_file_initialization_enabled
FROM sys.dm_server_services
WHERE servicename = 'SQL Server (MSSQLSERVER)'
Script para executar a instrução INSERT:
@limit -> aqui especifiquei o número de linhas a serem inseridas na tabela de teste
Para Linux, como executei o script usando SQLCMD, coloquei a função DATEDIFF no final. Ele me permite saber quantos segundos toda a execução leva (para a variante do Windows, eu poderia simplesmente dar uma olhada no cronômetro no SQL Server Management Studio).
Toda a string de 1.000.000 caracteres vai em vez de 'XXXX'. Estou colocando assim apenas para apresentá-lo bem neste 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 para executar a instrução DELETE
SET NOCOUNT ON
GO
DECLARE @StartTime DATETIME;
SET @StartTime = GETDATE();
DELETE FROM test.dbo.ubuntu;
SELECT DATEDIFF(SECOND,@StartTime,GETDATE()) AS 'Elapsed Seconds';
Os resultados obtidos
Todos os tamanhos são expressos em MB. Todas as medições de tempo são expressas em segundos.
INSERIR Hora | 1.000 registros | 5.000 registros | 10.000 registros | 25.000 registros | 50.000 registros |
Linux | 4 | 23 | 43 | 104 | 212 |
Janelas | 4 | 28 | 172 | 531 | 186 |
Tamanho (MDF) | 1.000 registros | 5.000 registros | 10.000 registros | 25.000 registros | 50.000 registros |
Linux | 264 | 1032 | 2056 | 5128 | 10184 |
Janelas | 264 | 1032 | 2056 | 5128 | 10248 |
Tamanho (LDF) | 1.000 registros | 5.000 registros | 10.000 registros | 25.000 registros | 50.000 registros |
Linux | 104 | 264 | 360 | 552 | 148 |
Janelas | 136 | 328 | 392 | 456 | 584 |
EXCLUIR Hora | 1.000 registros | 5.000 registros | 10.000 registros | 25.000 registros | 50.000 registros |
Linux | 1 | 1 | 74 | 215 | 469 |
Janelas | 1 | 63 | 126 | 357 | 396 |
EXCLUIR Tamanho (LDF) | 1.000 registros | 5.000 registros | 10.000 registros | 25.000 registros | 50.000 registros |
Linux | 136 | 264 | 392 | 584 | 680 |
Janelas | 200 | 328 | 392 | 456 | 712 |
Principais insights
- O tamanho do MDF foi bastante consistente em todo o teste, variando um pouco no final (mas nada muito louco).
- Os tempos para INSERTs foram melhores no Linux na maior parte, exceto no final, quando o Windows “ganhou a rodada”.
- O tamanho do arquivo de log de transações foi melhor tratado no Linux após cada rodada de INSERTs.
- Os tempos para DELETEs foram melhores no Linux na maior parte, exceto no final onde o Windows “ganhou a rodada” (acho curioso que o Windows também ganhou a rodada final de INSERT).
- O tamanho dos arquivos de log de transações após cada rodada de DELETEs era praticamente um empate em termos de altos e baixos entre os dois.
- Gostaria de testar com 100.000 linhas, mas estava com pouco espaço em disco, então limitei em 50.000.
Conclusão
Com base nos resultados obtidos neste teste, eu diria que não há motivos fortes para afirmar que a variante Linux tem um desempenho exponencialmente melhor do que sua contraparte Windows. Claro, isso não é de forma alguma um teste formal no qual você pode se basear para tomar tal decisão. No entanto, o exercício em si foi bastante interessante para mim.
Eu diria que o SQL Server 2019 para Windows às vezes fica um pouco atrasado (não muito) devido à renderização da GUI em segundo plano, o que não está acontecendo no lado do Ubuntu Server da cerca.
Se você confia muito em recursos e capacidades que são exclusivos do Windows (pelo menos no momento da redação deste artigo), então vá em frente. Caso contrário, dificilmente você fará uma má escolha ao optar por um em detrimento do outro.