1. Les Webcasts
Groupe des Utilisateurs SQL Server
Juin 2013 – Query memory grants
David Baffaleuf– CAPDATA
MVP SQL Server
2. David Baffaleuf
http://blog.capdata.fr
@dbaffaleuf
Leader SGBD reconnu en France
www.capdata.fr
Conseil
Service
Formation
DBA à distance
Management d’infrastructures IT hétérogènes
www.osmozium.com
Support Management
Technical Management
Data Management
Production Management
http://www.youtube.com/user/CapdataTV/
3. 30 ‘ chrono
• Comprendre qu’est-ce qu’un query memory grant
• Pourquoi ça peut être un problème
• Comment identifier
• Comment résoudre
• Démos !
• Questions / réponses
Query Memory Grants en 30’
4. De la mémoire pour une requête
Query Memory Grants en 30’
Plan
Compilation
Query
Memory
Grant
Max 75%
Buffer Pool
6. Evaluation des besoins
• 2 besoins évalués à la compilation :
– Mémoire requise (minimum grant): minimum syndical pour
supporter les opérateurs concernés. La requête ne peut pas
commencer son exécution sans cette valeur (par défaut, min
memory per query = 1Mb)
– Mémoire additionnelle (ideal grant): nécessaire pour faire toute la
passe (tri, hash) en mémoire. Pas obligatoire, pas garantie.
• Note: Pour optimiser les besoins, certains opérateurs peuvent
partager des fractions de QMG. (F4 sur opérateur)
Query Memory Grants en 30’
7. Arbitrage des QMG
• Demandes mémoire contrôlées par des sémaphores.
• 2 sémaphores par pool RG:
– Un pour les requêtes à faible coût ( cost < 3 && ideal grant < 5Mb)
– Un pour les requêtes à coût plus élevé (tout le reste)
• 3 sets par sémaphore (paramètre RG), une ou plusieurs queues
par set
– LOW SET: pool RG de faible importance
– MEDIUM SET: pool RG de moyenne importance
– HIGH SET: pool RG de haute importance
• Les requêtes à plus faible coût sont prioritaires sur les requêtes
au coût plus élevé.
Query Memory Grants en 30’
8. File d’attente et sémaphores 1/2
Query Memory Grants en 30’
SELECT TOP(1000)
* FROM Production.TransactionHistory
ORDER BY ActualCost DESC
OPTION (MAXDOP 1)
GO
RG POOL
DEFAULT
9. File d’attente et sémaphores 2/2
RG POOL (DEFAULT)
SMALL SEMAPHORE
(cost < 3 && ideal grant < 5Mb)
LARGE SEMAPHORE
(tout le reste)
LOW SET MEDIUM SET HIGH SET
LOW SET MEDIUM SET HIGH SET
Large RS, MEDIUM SET, qid=5
Query Memory Grants en 30’
5 queues par SET en Large RS:
- qid=0, cost < 10
- qid=1, 10<=cost < 99
- qid=2, 100<=cost < 999
- qid=3, 1000<=cost < 9999
- qid=4, cost > 10000
L
O
W
- qid=5, cost < 10
- qid=6, 10<=cost < 99
- qid=7, 100<=cost < 999
- qid=8, 1000<=cost < 9999
- qid=9, cost > 10000 …
M
E
D
10. Priorités et Attentes 1/2
• Une fois dans une des queues, la requête va devoir attendre que
150% de la mémoire demandée soir disponible, …
• … et qu’il n’y ait plus d’autres requêtes prioritaires.
• Les requêtes favorisées sont celles dont le coût est le plus faible et
l’importance la plus élevée.
• L’attente est comptabilisée sur RESOURCE_SEMAPHORE.
100+ requêtes
MEDIUM SET
QID = 0
Cost < 10
=> Prioritaires
Query Memory Grants en 30’
1 requête MEDIUM SET
QID = 2
100 < Cost < 999
Attente sur
RESOURCE_SEMAPHORE …
11. Priorités et Attentes 2/2
• Par défaut, la requête va attendre jusqu’à atteindre un timeout, qui est
égal à 25 fois le coût de la requête en secondes avec une limite de 24
heures (!!).
• Sinon paramètre instance query wait (s).
• Sinon request_memory_grant_timeout dans le pool RG.
• Lorsque le timeout est atteint:
– Soit l’ideal grant peut être réduit à la valeur de minimum grant, et le reste sera stocké sur disque
(tempdb).
– S’il n’y a plus assez de mémoire au runtime pour honorer le minimum, Erreur 8645: "A timeout
occurred while waiting for memory resources to execute the query in resource pool '%ls' (%ld).
Rerun the query."
Query Memory Grants en 30’
12. Pourquoi ça peut être un problème
• Ideal Grant = pas de garantie.
• Besoin évalué à la compilation et basé sur l’estimation des cardinalités
(nombre de lignes produites x taille de la ligne) en entrée de
l’opérateur.
• Au runtime, SQL Server peut n’accorder qu’une partie de ce qui a été
demandé en fonction de l’état des ressources, le reste se fera sur
disque en 1 ou plusieurs passes.
• Utilisation d’entrées / sorties synchrones (IO_COMPLETION).
• Mélange requêtes à fort coût et faible coût (DSS vs OLTP)
Query Memory Grants en 30’
14. Problème avec Hash match 2/2
• La phase de Build nécessite de réserver de la mémoire pour les N buckets créés
(estimation des cardinalités).
• Les buckets qui ne tiennent pas en mémoire vont sur disque (tempdb).
• Les lignes de probe qui joignent des buckets sur disque vont sur disque (tempdb).
• Une fois que toutes les jointures sur les buckets en mémoire sont terminées, on va relire
les buckets + lignes de probe sur disque.
• Si la seconde passe ne tient pas davantage en mémoire, certains couples buckets +
probes sont réécrites sur disque (recursion).
• Trop de recursion => Hash bailout. On laisse tomber la table de hachage et la
jointure est faite en utilisant un NLJ non optimisé.
• Visible avec SQL Trace : Hash Warning ou Xevent : hash_warning (map = bailout), et
depuis SQL Server 2012 un avertissement dans l’opérateur.
• Compteur perfmon: Workfiles created /sec
Query Memory Grants en 30’
15. Problème avec Sort
• Algoritme Quicksort trie en mémoire.
• Si le memory grant est dépassé, tout le tri va sur disque (tempdb) et
utilise un algoritme merge sort moins efficace.
• Visible grâce à SQL Trace: Sort Warning ou Xevent : sort_warning, et
depuis SQL Server 2012 un avertissement dans l’opérateur.
• Techniquement ni worktable ni workfile.
Query Memory Grants en 30’
16. Problème avec Exchange 1/2
• Nécessite DOP*2 buffers par flux (producteur / consommateur).
– Distribute: 1 flux en entrée + DOP flux en sortie.
– Repartition: DOP flux en entrée + DOP flux en sortie.
– Gather: DOP flux en entrée + 1 flux en sortie.
• La taille du buffer est déterminée en fonction de l’estimation des
cardinalités .
Query Memory Grants en 30’
DOP = 8
DOP*2
Buffers
DOP*2
Buffers
DOP*2
Buffers
DOP*2
Buffers
17. Problème avec Exchange 2/2
• Arrive rarement. Souvent visible sur un Merge Exchange (parallélisme
+ ORDER BY, MJ, Stream AGG) lorsque l’ordre doit être préservé.
• Lorsqu’un worker récupère plus de lignes que les autres, et que
l’opérateur Merge ne peut plus préserver l’ordre, l’ensemble des
lignes en entrées vont sur disque (Intra-Query Parallel Deadlock)
• Visible grâce à SQL Trace: Exchange Spill Event ou Xevent :
exchange_spill .
Query Memory Grants en 30’
1 2 3 4 5 6 7 8 9 10
1 3 4 5 6 7 8 10
2 9
1 2 3
x
18. Comment détecter les problèmes de QMG
• DBCC MEMORYSTATUS
Small Query Memory Objects (RG Pool, en pages)
Query Memory Objects (RG Pool, en pages)
• DMO:
sys.dm_exec_query_resource_semaphores
sys.dm_exec_query_memory_grants
sys.dm_os_waiting_tasks (RESOURCE_SEMAPHORE)
• Évènements SQL Trace:
Hash Warning
Sort Warning
Exchange Spill Event.
Trace par défaut (v >= 2012)
• Évènements XEvents:
hash_warning
sort_warning
exchange_spill.
Query Memory Grants en 30’
19. Comment résoudre les problèmes de QMG
• Indexation
• Réécriture des requêtes
• Gérer les priorités en utilisant les pools de ressource RG.
• Plus de mémoire…
Query Memory Grants en 30’
A propos du //: DOP dependenceIf SQL server has more than 1 CPU, it can run a query in parallel mode for improved performance by sharing work among parallel workers. These workers run independent of each other, and use "parallelism operator (a.k.a. exchange)" to transfer processed rows. This parallel mode increases memory usage because each worker needs its own copy of sort or hash join, and the parallelism operator needs buffers for temporary storage of transferred rows. Since DOP N would use N parallel workers, the query would need N times more required memory. On the other hand, the total number of rows to handle (and memory cost to store them) does not change with DOP. This means that the additional memory would stay the same regardless of DOP setting. Starting with SQL 2008, the buffer memory used by parallelism operator is also counted as a required part of memory grant.
Les tris ou hashes ont une phase de ‘build’ qui utilise plus de mémoire que leur phase d’exécution proprement dite. La mémoire relâchée par une phase de build va pouvoir être réutilisée par un autre opérateur dans le plan.
Importance = parameter in RG
- small RS: cost < 3 and grant size < 5Mb
|__ Low importance set: 1 queue
|__ Medium importance set: 1 queue
|__ High importance set: 1 queue
- large RS: everythg else
|__ Low importance set: 5 queues
|__ cost < 10 (queue_id = 0 in sys.dm_exec_query_memory_grants)
|__ 10 =< cost < 99 (queue_id = 1 in sys.dm_exec_query_memory_grants)
|__ 100 =< cost < 999 (queue_id = 2 in sys.dm_exec_query_memory_grants)
|__ 10000 =< cost < 9999 (queue_id = 3 in sys.dm_exec_query_memory_grants)
|__ cost > 10000 (queue_id = 4 in sys.dm_exec_query_memory_grants)
|__ Medium importance set: 5 queues
|__ High importance set: 5 queues
Smaller cost queries are prioritized over larger cost.
Importance = parameter in RG
- small RS: cost < 3 and grant size < 5Mb
|__ Low importance set: 1 queue
|__ Medium importance set: 1 queue
|__ High importance set: 1 queue
- large RS: everythg else
|__ Low importance set: 5 queues
|__ cost < 10 (queue_id = 0 in sys.dm_exec_query_memory_grants)
|__ 10 =< cost < 99 (queue_id = 1 in sys.dm_exec_query_memory_grants)
|__ 100 =< cost < 999 (queue_id = 2 in sys.dm_exec_query_memory_grants)
|__ 10000 =< cost < 9999 (queue_id = 3 in sys.dm_exec_query_memory_grants)
|__ cost > 10000 (queue_id = 4 in sys.dm_exec_query_memory_grants)
|__ Medium importance set: 5 queues
|__ High importance set: 5 queues
Smaller cost queries are prioritized over larger cost.
9,4 * 25 = 3 minutes 55 secondes
Bien plus méchant que pour le HASH. Si on dépasse le QMG de qq buckets, ce n’est pas terriblement grave, on va faire une passe sur disque. Alors que si on dépasse d’un iota le QMG pour un tri, tout le tri part sur disque.
DBCC MEMORYSTATUS changes in SQL Server 2012:
Buffer Pool Target Pages => Memory manager (Target Committed KB) in SQL Server 2012
QMO et SQMO exprimé en pages
Target = 1024000 KB
(92625 + 4875) * 8 = 780000 => 0.75 de 1024000
DBCC MEMORYSTATUS changes in SQL Server 2012:
Buffer Pool Target Pages => Memory manager (Target COmmitted KB) in SQL Server 2012