取出使用最多的10条慢查询
./mysqldumpslow -s c -t 10 /export/data/mysql/log/slow.log
取出查询时间最慢的3条慢查询
./mysqldumpslow -s t -t 3 /export/data/mysql/log/slow.log
注意: 使用mysqldumpslow的分析结果不会显示具体完整的sql语句,只会显示sql的组成结构;
假如: SELECT FROM sms_send WHERE service_id=10 GROUP BY content LIMIT 0, 1000;
mysqldumpslow命令执行后显示:
Count: 2 Time=1.5s (3s) Lock=0.00s (0s) Rows=1000.0 (2000), vgos_dba[vgos_dba]@[10.130.229.196]SELECT FROM sms_send WHERE service_id=N GROUP BY content LIMIT N, N
不使用子查询
SELECT FROM t1 WHERE id (SELECT id FROM t2 WHERE name=’hechunyang’);
子查询在MySQL5.5版本里,内部执行计划器是这样执行的:先查外表再匹配内表,而不是先查内表t2,当外表的数据很大时,查询速度会非常慢。
在MariaDB10/MySQL5.6版本里,采用join关联方式对其进行了优化,这条SQL会自动转换为 SELECT t1. FROM t1 JOIN t2 ON t1.id = t2.id;
但请注意的是:优化只针对SELECT有效,对UPDATE/DELETE子 查询无效, 生产环境尽量应避免使用子查询。
避免函数索引
SELECT FROM t WHERE YEAR(d) >= 2016;
由于MySQL不像Oracle那样⽀持函数索引,即使d字段有索引,也会直接全表扫描。
应改为 > SELECT FROM t WHERE d >= ‘2016-01-01’;
用IN来替换OR低效查询
慢SELECT FROM t WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30;
高效查询 > SELECT FROM t WHERE LOC_IN IN (10,20,30);
LIKE双百分号无法使用到索引
SELECT FROM t WHERE name LIKE ‘%de%’;
使用SELECT FROM t WHERE name LIKE ‘de%’;
分组统计可以禁止排序
SELECT goods_id,count() FROM t GROUP BY goods_id;
默认情况下,MySQL对所有GROUP BY col1,col2…的字段进⾏排序。如果查询包括GROUP BY,想要避免排序结果的消耗,则可以指定ORDER BY NULL禁止排序。
使用SELECT goods_id,count() FROM t GROUP BY goods_id ORDER BY NULL;
禁止不必要的ORDER BY排序
SELECT count(1) FROM user u LEFT JOIN user_info i ON u.id = i.user_id WHERE 1 = 1 ORDER BY u.create_time DESC;
使用SELECT count(1) FROM user u LEFT JOIN user_info i ON u.id = i.user_id;