Come determinare il sort_buffer_size ottimale?


10

Ho letto da un file di configurazione di esempio che dice quanto segue:

# 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.

Ho un paio di domande che usano filesort. Come posso determinare qual è la dimensione del buffer necessario per il corretto funzionamento delle query senza colpire il disco?


Hai eseguito mysqltuner o tuning-primer In queste app potresti vedere qualcosa di interessante sul tuo my.cnf.
David Martinez,

Risposte:


14

C'è solo una variabile di stato che si preoccupa di sort_buffer_size . Questo è quello che hai nel messaggio nella domanda: Sort_merge_passes . La documentazione di MySQL dice:

Sort_merge_passes: il numero di passaggi di merge che l'algoritmo di ordinamento ha dovuto eseguire. Se questo valore è elevato, è necessario aumentare il valore della variabile di sistema sort_buffer_size .

Tieni presente una cosa su sort_buffer_size

Se nell'output SHOW GLOBAL STATUS vengono visualizzati molti passi Sort_merge al secondo, è possibile considerare di aumentare il valore sort_buffer_size per velocizzare le operazioni ORDER BY o GROUP BY che non possono essere migliorate con l'ottimizzazione delle query o l'indicizzazione migliorata

Mentre la raccolta di sort_buffer_sizedomande può aiutare con GROUP BYs e ORDER BYs, si sta meglio migliorando le query che si può migliorare e aggiungendo gli indici che possono essere utilizzati da Query Optimizer.

La domanda rimane: come si fa a controllare i Sort_merge_passes ???

Utilizzare questo codice per verificare il numero di Sort_merge_passes negli ultimi 5 minuti. Calcola anche i Sort_merge_passes all'ora.

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 trovi Sort_merge_passes e la tariffa è troppo alta, sentiti libero di aumentare sort_buffer_size . Supponiamo di voler aumentare a 4M. Faresti questo:

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

Aggiungeresti quindi questo a my.cnf

[mysqld]
sort_buffer_size = 4M

Dovresti eseguire periodicamente il codice per verificare altre volte picchi di Sort_merge_passes .


2
Questa è la risposta molto migliore
Greg

7
@RolanoMySQLDBA puoi definire "molti" nel modo seguente: "Se vedi molti Sort_merge_passes al secondo"
Tarek,

2

Non è necessario modificare sort_buffer_size per impostazione predefinita. Si fraintende il suo utilizzo in base alla domanda. Si dovrebbe iniziare esaminando l'SQL per vedere se si è in grado di ottimizzarlo e soddisfare le condizioni ORDER BY / GROUP BY utilizzando un indice. Sarà generalmente un indice composito.

Inoltre: http://www.xaprb.com/blog/2010/05/09/how-to-tune-mysqls-sort_buffer_size/


Mi dispiace dire che trovo quel post difficilmente utile. È come dire alla gente di non fare qualcosa solo perché non sei un esperto. Come sottolineato dal primo commentatore, i .cnffile di esempio forniti con mysql non utilizzano l'impostazione predefinita.
Domanda Overflow

Se lo rileggi, dice anche che l'esperto sa già di non modificare il valore di default. I file .cnf di esempio non devono essere utilizzati o indicati come buona pratica. Se hai bisogno di aiuto per creare un file my.cnf, Percona offre una procedura guidata abbastanza approfondita. tools.percona.com/wizard
eroomydna

2

La guida nel manuale (5.0-5.5) è

Se nell'output SHOW GLOBAL STATUS vengono visualizzati molti passi Sort_merge al secondo, è possibile considerare di aumentare il valore sort_buffer_size per velocizzare le operazioni ORDER BY o GROUP BY che non possono essere migliorate con l'ottimizzazione delle query o l'indicizzazione migliorata. L'intero buffer viene allocato anche se non è tutto necessario, quindi impostarlo su un valore maggiore di quello richiesto a livello globale rallenterà la maggior parte delle query che ordinano. È consigliabile aumentarlo come impostazione di sessione e solo per le sessioni che richiedono dimensioni maggiori. Su Linux, ci sono soglie di 256 KB e 2 MB in cui valori più grandi possono rallentare in modo significativo l'allocazione della memoria, quindi è necessario considerare di rimanere al di sotto di uno di questi valori. Sperimenta per trovare il valore migliore per il tuo carico di lavoro.

Da 5.6 in poi il testo indica che l'ottimizzatore può scegliere un valore per una query e che il server può estendere il buffer fino al limite. Ciò mitiga il costo di impostazione del valore troppo alto. Quindi sembra che tu possa voler essere conservativo, inferiore a quello predefinito (come fanno i file cnf di rilascio) per le versioni sotto 5.6.4 ma può permettersi di avere un limite più alto di dire i 2 MB predefiniti, o anche di più, da 5.6. 4 poiché l'intero importo non è assegnato alla cieca.

A partire da MySQL 5.6.4, l'ottimizzatore cerca di capire quanto spazio è necessario ma può allocare di più, fino al limite.


1

Il modo migliore per determinare l'ottimale sort_buffer_sizeè confrontarlo.

Come? Come @RolandoMySQLDBA, il controllo Sort_merge_passespotrebbe essere utile, ma non è l'unico fattore che influenza le prestazioni. Dovresti stare attento quando aumenti il sort_buffer_size.

Il documento dice questo

Su Linux, ci sono soglie di 256 KB e 2 MB in cui valori più grandi possono rallentare in modo significativo l'allocazione della memoria, quindi si dovrebbe considerare di rimanere al di sotto di uno di questi valori.

C'è un post sui test che lo conclude

sort_merge_passesnon sono poi così male. Impostare il tuo sort_buffer_sizeabbastanza grande in modo che non ci sia zero sort_merge_passespotrebbe non essere ottimale.

Quando ho provato, ho anche ottenuto un risultato simile.

Idealmente, sarebbe meglio evitare la situazione che è necessario ottimizzare sort_buffer_size. Come? Questo documento di ORDER BY Optimization potrebbe aiutarti a capire come funzionano le cose sotto il cofano.


-1

"mysql> SET GLOBAL sort_buffer_size = 1024 * 1024 * 4;" è un brutto modo di mettere in 4m la dimensione del buffer di ordinamento, questo fa sì che la dimensione del buffer di ordinamento abbia un uso di 4 GB

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

Se sono stato tuo, non provo a cambiare la dimensione del buffer corto, questo è un buon modo per fare in modo che il tuo server si arresti in modo anomalo e inviarlo al cestino. È meglio provare a fare query migliori.


1
Come può avvenire un ordinamento di grandi dimensioni in un buffer di ordinamento 4K? Nota che hai detto 1024 * 4. Sono 4096, 4K.
RolandoMySQLDBA

Cosa ha detto Rolando ^^. E il valore minimo consentito è 32K.
ypercubeᵀᴹ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.