La base est lente
Symptôme
Lenteur à l'échelle de l'application ; les requêtes prennent bien plus de temps que d'habitude et les utilisateurs se plaignent.
1. Précisez d'abord ce qui est lent
Tout est-il lent, ou une requête/un écran précis ? Quand cela a-t-il commencé, et cela coïncide-t-il avec un déploiement/un patch/une croissance des données ? Est-ce global ou limité à une seule base ? Cela ramène la recherche à un axe : CPU, E/S, verrouillage ou changement de plan.
2. Examinez les sessions actives et les événements d'attente
Qu'est-ce qui s'exécute et qu'est-ce qui attend en ce moment ? Un événement d'attente dominant (E/S, verrou, log) indique le goulet d'étranglement.
Oracle
SELECT sid, username, status, event, sql_id FROM v$session WHERE status='ACTIVE' AND type='USER';PostgreSQL
SELECT pid, state, wait_event_type, wait_event, query FROM pg_stat_activity WHERE state='active';MySQL
SELECT id, user, command, time, state, info FROM information_schema.processlist WHERE command<>'Sleep' ORDER BY time DESC;SQL Server
SELECT session_id, status, wait_type, wait_time, blocking_session_id FROM sys.dm_exec_requests WHERE session_id IN (SELECT session_id FROM sys.dm_exec_sessions WHERE is_user_process = 1);MongoDB
db.currentOp({ active: true, secs_running: { $gt: 1 } })Redis
SLOWLOG GET 103. Recherchez les blocages
La cause la plus fréquente de lenteur est une session qui en bloque d'autres. Trouvez la session bloquante et identifiez la tête de la chaîne.
Oracle
SELECT blocking_session, sid, seconds_in_wait, event FROM v$session WHERE blocking_session IS NOT NULL;PostgreSQL
SELECT pid, pg_blocking_pids(pid) AS blocked_by, query FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid))>0;MySQL
SELECT * FROM sys.innodb_lock_waits\GSQL Server
SELECT session_id, blocking_session_id, wait_type FROM sys.dm_exec_requests WHERE blocking_session_id<>0;4. Extrayez les requêtes les plus coûteuses
Trouvez les 10 requêtes qui consomment le plus de ressources. En général, 90 % du problème vient d'une poignée de requêtes.
Oracle
SELECT sql_id, elapsed_time/1e6 sec, executions, sql_text FROM v$sql ORDER BY elapsed_time DESC FETCH FIRST 10 ROWS ONLY;PostgreSQL
SELECT calls, total_exec_time, mean_exec_time, query FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;MySQL
SELECT digest_text, count_star, sum_timer_wait/1e12 sec FROM performance_schema.events_statements_summary_by_digest ORDER BY sum_timer_wait DESC LIMIT 10;SQL Server
SELECT TOP 10 total_elapsed_time/execution_count avg_us, execution_count, SUBSTRING(t.text,1,200) FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) t ORDER BY total_elapsed_time DESC;5. Examinez le plan de la requête suspecte
Obtenez l'EXPLAIN de la requête lente. Cherchez les full table scans, les index manquants, un mauvais ordre de jointure ou des statistiques obsolètes. Si le plan a changé soudainement, envisagez de collecter les statistiques.
Oracle
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id', NULL, 'ALLSTATS LAST'));PostgreSQL
EXPLAIN (ANALYZE, BUFFERS) <query>;MySQL
EXPLAIN ANALYZE <query>;SQL Server
SET STATISTICS PROFILE ON; <query>; SET STATISTICS PROFILE OFF;MongoDB
db.my_collection.find({...}).explain('executionStats') // COLLSCAN or IXSCAN?6. Vérifiez les ressources système
Au niveau OS, vérifiez le CPU, l'attente E/S (iowait), la mémoire et l'utilisation disque. Vérifiez le cache hit ratio ; s'il est faible, il peut y avoir un goulet mémoire. Le problème peut se situer hors de la base (disque plein, VM voisine bruyante).
7. Décidez : correctif rapide ou définitif
Pour un soulagement immédiat : tuez la requête incontrôlée, ajoutez l'index manquant, collectez les statistiques. Pour un correctif définitif : revoyez la requête/l'index, corrigez les paramètres mémoire, assurez la stabilité des plans (baseline/hint).