Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Teste de desempenho do MS SQL Server no Linux vs Windows para identificar a diferença


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?

  1. 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)).
  2. 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.