Olá pessoal,
Bom dia!

Neste post, vou apresentar e demonstrar a utilização da ferramenta open-source SQLQueryStress, do Adam Machanic (criador da sp_WhoIsActive), que serve para realizar testes de stress executando uma determinada query, permitindo que você realize uma série de testes na sua instância SQL. Como esse projeto não é mais mantido e atualizado pelo Adam, o Erik Ejlskov Jensen criou um Github para criar novos recursos e melhorias para a ferramenta.

A ferramenta permite que você defina quantas threads serão executadas simultaneamente, quantas execuções e qual o intervalo de tempo entre cada execução, permitindo realizar vários tipos de testes, das quais destaco:

  • Verificar o comportamento da instância com uma determinada quantidade de sessões em execução
  • Executar várias queries ao mesmo tempo para estressar a CPU, disco e memória do servidor e verificar o seu comportamento
  • Simulação de um ambiente crítico com várias transações por segundo durante os testes de sistemas e consultas SQL
  • Identificar quantas vezes uma SP é executada por dia, realizar uma otimização e simular qual seria o ganho de tempo no dia
  • Executar uma query ou SP várias vezes, com parâmetros aleatórios e analisar seu comportamento

Enfim, a lista de possibilidades é muito grande e o software te dá várias ferramentas para melhorar sua análise, como possibilidade de utilizar ou não, o Pool de conexões, limpar caches, limpar buffer, etc.

A utilização da ferramenta é bem simples, por isso não vou fazer muitas demonstrações. O intuito desse post é compartilhar essa ferramenta para quem ainda não a conhecia, de forma que possa melhorar suas análises sobre a performance das instâncias SQL Server que você demonstra ou fazer testes de performance em alguma query.

Após baixar o executável da ferramenta neste link, você verá a tela inicial do SQLQueryStress. Clique no botão “Database” para configurar a conexão com o banco de dados.

Não recomendo a utilização desse software em ambientes de produção, a não ser que seja em um horário de manutenção agendada e que você queira fazer testes de stress na instância.

Tela inicial do SQLQueryStress

Nesta tela, você poderá digitar o nome do servidor\instância de conexão, bem como dados de tipo de autenticação, usuário e senha.

Tela de configuração de conexão com o banco de dados

De volta à tela inicial, vamos definir a query que será executada, os parâmetros de execução e iniciar o processamento.

Parâmetros de execução:
Number of Iterations: É o número de vezes que a query será executada
Number of Threads: Número de sessões que serão executadas em paralelo (ao mesmo tempo)
Delay between queries (ms): Quantidade de millisegundos entre o fim de uma query e o início da próxima.

Vale ressaltar que o número de vezes que a query será executada é através da conta Number of Iterations x Number of Threads, ou seja, se você colocar 10 iterações com 5 threads, a sua query será executada 50 vezes.

Resultado da execução:

Resultado do WhoIsActive, demonstrando as conexões sendo executadas:

(Obs: Tive que colocar um WAITFOR DELAY na SP para que elas apareçam no WhoIsActive, uma vez que a SP de teste é muito simples e roda muito rápido)

Como utilizar o Parameter Substitution

Clique aqui para saber mais sobre o Parameter Substitution
Um recurso muito legal que vou mostrar é o Parameter Substitution, que permite executar queries e SP’s passando parâmetros baseado no retorno de uma query.

Neste exemplo, vou criar uma tabela e inserir vários valores aleatórios que serão utilizados como parâmetros para as chamadas da SP que vou testar no SQLQueryStress.

Criação da função para gerar números aleatórios:

IF (OBJECT_ID('dbo.fncRand') IS NOT NULL) DROP FUNCTION dbo.fncRand
GO

/*
Vou criar uma função para usar no SELECT e realmente trazer valores aleatórios
para cada linha
*/
CREATE FUNCTION dbo.fncRand(@Numero BIGINT)
RETURNS BIGINT
AS
BEGIN
    RETURN (ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0) * @Numero
END
GO

Geração dos dados aleatórios para testes

IF (OBJECT_ID('dbo.Testes') IS NOT NULL) DROP TABLE dbo.Testes
CREATE TABLE dbo.Testes (
    Nome VARCHAR(60),
    Dt_Nascimento DATETIME,
    CPF VARCHAR(11)
)


-- Carga inicial
INSERT INTO dbo.Testes
SELECT
    CAST(NEWID() AS VARCHAR(50)) AS Nome,
    DATEADD(DAY, dbo.fncRand(12000), '1980-01-01') AS Dt_Nascimento,
    RIGHT(REPLICATE('0', 11) + CAST(dbo.fncRand(99999999999) AS VARCHAR(11)), 11) AS CPF


DECLARE @Contador INT = 1, @Total INT = 16

WHILE(@Contador <= @Total)
BEGIN

    -- Executo esse trecho várias vezes
    INSERT INTO dbo.Testes
    SELECT
        CAST(NEWID() AS VARCHAR(50)) AS Nome,
        DATEADD(DAY, dbo.fncRand(12000), '1980-01-01') AS Dt_Nascimento,
        RIGHT(REPLICATE('0', 11) + CAST(dbo.fncRand(99999999999) AS VARCHAR(11)), 11) AS CPF
    FROM
        dbo.Testes


    SET @Contador += 1


END

Exemplo de tabela com dados aleatórios:

Uma vez que a tabela com os dados de teste já foi criada e populada, basta configurar no software a substituição dos parâmetros:


É isso aí, pessoal!
Espero que tenham gostado desse post e dessa excelente ferramenta para testar queries e o limite de processamento da sua instância SQL Server.
Um abraço e até a próxima.