查找最慢 / 开销最大的查询
Oracle
SELECT sql_id,
ROUND(elapsed_time/1e6, 1) AS elapsed_sec,
executions,
ROUND(elapsed_time/1e6/NULLIF(executions,0), 3) AS sec_per_exec,
sql_text
FROM v$sql
ORDER BY elapsed_time DESC
FETCH FIRST 10 ROWS ONLY;历史分析使用 AWR:dba_hist_sqlstat。有了 sql_id,DBMS_XPLAN.DISPLAY_CURSOR 可显示执行计划。
PostgreSQL
SELECT calls,
ROUND(total_exec_time::numeric, 1) AS total_ms,
ROUND(mean_exec_time::numeric, 2) AS mean_ms,
query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;需要 pg_stat_statements 扩展(shared_preload_libraries)。使用 pg_stat_statements_reset() 重置。
MySQL
SELECT digest_text,
count_star AS calls,
ROUND(sum_timer_wait/1e12, 2) AS total_sec,
ROUND(avg_timer_wait/1e9, 2) AS avg_ms
FROM performance_schema.events_statements_summary_by_digest
ORDER BY sum_timer_wait DESC
LIMIT 10;替代方案:开启 slow_query_log = ON 并设置 long_query_time 的慢查询日志。
SQL Server
SELECT TOP 10
qs.execution_count,
qs.total_elapsed_time/1000 AS total_ms,
qs.total_elapsed_time/qs.execution_count/1000 AS avg_ms,
SUBSTRING(t.text, 1, 200) AS sql_text
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) t
ORDER BY qs.total_elapsed_time DESC;如果启用了 Query Store,可使用 sys.query_store_runtime_stats 进行更丰富的历史分析。
MongoDB
// Enable the profiler for operations over 100ms:
db.setProfilingLevel(1, { slowms: 100 })
// Then read the slowest ones:
db.system.profile.find().sort({ millis: -1 }).limit(10)profiler 会增加写入开销;诊断结束后用 db.setProfilingLevel(0) 关闭。
Redis
SLOWLOG GET 10
# Set the threshold (microseconds): CONFIG SET slowlog-log-slower-than 10000slowlog-log-slower-than 以微秒为单位(10000 = 10 ms)。使用 SLOWLOG RESET 清空。