Como determinar o sort_buffer_size ideal?

10

Eu li de um arquivo de configuração de amostra que diz o seguinte:

# Sort buffer is used to perform sorts for some ORDER BY and GROUP BY
# queries. If sorted data does not fit into the sort buffer, a disk
# based merge sort is used instead - See the "Sort_merge_passes"
# status variable. Allocated per thread if sort is needed.

Eu tenho algumas consultas que usam filesort. Como determino qual é o tamanho do buffer necessário para que as consultas sejam executadas sem problemas, sem atingir o disco?

Pergunta Overflow
fonte
Você já executou o mysqltuner ou o tuning-primer? Você pode ver algo interessante sobre o my.cnf nesses aplicativos.
David Martinez

Respostas:

14

Há apenas uma variável de status que se preocupa com sort_buffer_size . É isso que você tem na mensagem de volta à pergunta: Sort_merge_passes . A documentação do MySQL diz:

Sort_merge_passes: o número de passes de mesclagem que o algoritmo de classificação teve que fazer. Se esse valor for grande, considere aumentar o valor da variável de sistema sort_buffer_size .

Lembre-se de uma coisa sobre o sort_buffer_size

Se você ver muitos Sort_merge_passes por segundo na saída SHOW GLOBAL STATUS, considere aumentar o valor sort_buffer_size para acelerar as operações ORDER BY ou GROUP BY que não podem ser aprimoradas com otimização de consulta ou indexação aprimorada

Embora o aumento sort_buffer_sizepossa ajudar as consultas com GROUP BYs e ORDER BYs, é melhor melhorar as consultas e adicionar índices que podem ser usados ​​pelo Query Optimizer.

A pergunta permanece: Como você verifica os Sort_merge_passes ???

Use esse código para verificar quantas Sort_merge_passes ocorreram nos últimos 5 minutos. Ele também calcula o Sort_merge_passes por hora.

SET @SleepTime = 300;
SELECT variable_value INTO @SMP1
FROM information_schema.global_status WHERE variable_name = 'Sort_merge_passes';
SELECT SLEEP(@SleepTime) INTO @x;
SELECT variable_value INTO @SMP2
FROM information_schema.global_status WHERE variable_name = 'Sort_merge_passes';
SET @SMP = @SMP2 - @SMP1;
SET @SMP_RATE = @SMP * 3600 / @SleepTime;
SELECT @SMP,@SMP_RATE;

Se você encontrar o Sort_merge_passes e a taxa muito alta, fique à vontade para aumentar o sort_buffer_size . Suponha que você queira aumentar para 4M. Você executaria isso:

mysql> SET GLOBAL sort_buffer_size = 1024 * 1024 * 4;

Você adicionaria isso ao my.cnf

[mysqld]
sort_buffer_size = 4M

Você executaria o código periodicamente para verificar outras vezes os picos de Sort_merge_passes .

RolandoMySQLDBA
fonte
2
Esta é a resposta muito melhor
Greg
7
@RolanoMySQLDBA você pode definir "muitos" no seguinte: "Se você ver muitos Sort_merge_passes por segundo"
Tarek,
2

Você não precisa alterar o sort_buffer_size do padrão. Você entende mal o seu uso com base na pergunta. Você deve começar examinando o SQL para ver se é capaz de ajustá-lo e satisfazer as condições ORDER BY / GROUP BY usando um índice. Geralmente será um índice composto.

Além disso: http://www.xaprb.com/blog/2010/05/09/how-to-tune-mysqls-sort_buffer_size/

eroomydna
fonte
Lamento dizer que acho esse post pouco útil. É como dizer às pessoas para não fazerem algo apenas porque você não é um especialista. Conforme apontado pelo primeiro comentarista, os .cnfarquivos de amostra enviados com o mysql não usam a configuração padrão.
Pergunta Overflow
Se você ler novamente, também diz que o especialista já sabe que não deve alterar o valor do padrão. Os arquivos .cnf de exemplo não devem ser usados ​​ou referenciados como boas práticas. Se você precisar de ajuda para criar um arquivo my.cnf, o Percona oferece um assistente bastante completo. tools.percona.com/wizard
eroomydna
2

As orientações no manual (5.0-5.5) são

Se você ver muitos Sort_merge_passes por segundo na saída SHOW GLOBAL STATUS, considere aumentar o valor sort_buffer_size para acelerar as operações ORDER BY ou GROUP BY que não podem ser aprimoradas com otimização de consulta ou indexação aprimorada. Todo o buffer é alocado, mesmo que nem tudo seja necessário, portanto, configurá-lo maior do que o necessário globalmente reduzirá a maioria das consultas desse tipo. É melhor aumentá-lo como uma configuração de sessão e apenas para as sessões que precisam de um tamanho maior. No Linux, existem limites de 256 KB e 2 MB em que valores maiores podem diminuir significativamente a alocação de memória; portanto, você deve ficar abaixo de um desses valores. Experimente encontrar o melhor valor para sua carga de trabalho.

A partir da versão 5.6, o texto indica que o otimizador pode escolher um valor para uma consulta e que o servidor pode estender o buffer até o limite. Isso reduz o custo de definir o valor muito alto. Parece que você pode querer ser conservador, menor que o padrão (como os arquivos cnf da versão) para versões abaixo da 5.6.4, mas pode ter um limite maior de dizer os 2 MB padrão, ou até mais, da versão 5.6. 4, pois o valor total não é cego.

A partir do MySQL 5.6.4, o otimizador tenta descobrir quanto espaço é necessário, mas pode alocar mais, até o limite.

ClearCrescendo
fonte
1

A melhor maneira de determinar o ideal sort_buffer_sizeé compará-lo.

Quão? Como o @RolandoMySQLDBA disse que a verificação Sort_merge_passespode ser útil, mas esse não é o único fator que afeta o desempenho. Você deve ter cuidado ao aumentar osort_buffer_size .

O documento diz que

No Linux, existem limites de 256 KB e 2 MB em que valores maiores podem diminuir significativamente a alocação de memória, portanto, você deve ficar abaixo de um desses valores.

um post sobre o teste que conclui que

sort_merge_passesnão é tão ruim assim. Configurando seu sort_buffer_sizetamanho suficiente para que haja zerosort_merge_passes não pode ser o ideal.

Quando testei, também obtive um resultado semelhante.

Idealmente, seria melhor evitar a situação que você precisa para otimizar o sort_buffer_size. Quão? Este documento de ORDEM POR Otimização pode ajudá-lo a entender como as coisas funcionam sob o capô.

Sanghyun Lee
fonte
-1

"mysql> SET GLOBAL sort_buffer_size = 1024 * 1024 * 4;" é uma maneira ruim de colocar em 4m o tamanho do buffer de classificação, isso faz com que o tamanho do buffer de classificação use 4 GB

"mysql> SET GLOBAL sort_buffer_size = 1024 * 4;"

Se eu sou seu, não tento alterar o tamanho curto do buffer, é uma boa maneira de travar o servidor e enviar para o desempenho do lixo. É melhor tentar fazer consultas melhores.

Moorer
fonte
11
Como pode ocorrer uma classificação grande em um buffer de classificação 4K? Note que você disse 1024 * 4. Isso é 4096, 4K.
RolandoMySQLDBA
O que Rolando disse ^^. E o valor mínimo permitido é 32K.
ypercubeᵀᴹ