主要思路:解决order by 引起的排序无法索引的问题。解决方法,将所有查询条件字段和排序字段创建联合索引。
ex:
explain SELECT
a.valid,
c. NAME AS bankname,
d.paraName AS state,
e.`name` AS username,
a.jhstatus,
a.moneybalance,
f.bizname,
b.phone_self2 AS phoneSelf2
FROM
`case`.t_case_jhs123_head a
LEFT JOIN `case`.t_case_jhs123_details b ON a.caseid = b.caseid
LEFT JOIN golddb.t_bank c ON a.bankid = c.bankcode
LEFT JOIN golddb.t_basedata d ON a.state = d.id
LEFT JOIN zwy.zwy_user e ON a.userid = e.id
LEFT JOIN golddb.t_biz_type f ON a.biztype = f.bizcode
WHERE
(a.userid IN(3505))
AND a.allot = 1
AND a.state = '38'
AND a.onhandstatus = 0
ORDER BY
a.money DESC
LIMIT 0,
30;
执行计划:
此处的using temporary是临时表 由distinct引起这里直接删除distinct 。
添加联合索引:
ALTER table t_case_jhs123_head add index (userid,allot,state,onhandstatus,money);
执行结果:
使用了联合索引。
以下是理论及案例:
原文地址:http://blog.csdn.net/yangyu112654374/article/details/4251624
用Explain分析SQL语句的时候,经常发现有的语句在Extra列会出现Using filesort,根据MySQL官方文档对他的描述:
中文手册上翻译的很别扭:
总的来说,Using filesort 是mysql里一种速度比较慢的外部排序,如果能避免是最好的了,很多时候,我们可以通过优化索引来尽量避免出现Using filesort,从而提高速度。
这里举个简单的例子:
写个存储过程askwan,插入10万条测试数据
OK,数据准备好了,开始试验。
由上面例子中建立的表信息,我已经建立了两个索引,一个主键id,一个room_number列索引
那现在来看一条SQL,
分析一下
mysql> EXPLAIN SELECT id FROM testing WHERE room_number=1000 ORDER BY id ; +----+-------------+---------+------+---------------+-------------+---------+-------+------+-----------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------+---------------+-------------+---------+-------+------+-----------------------------+ | 1 | SIMPLE | testing | ref | room_number | room_number | 4 | const | 1 | Using where; Using filesort | +----+-------------+---------+------+---------------+-------------+---------+-------+------+-----------------------------+ 1 row in set (0.00 sec)
出现了Using filesort,并且用到了room_number这列索引,但是,在这里用到的索引是针对WHERE后面的room_number条件的,而最后面的排序是根据id来的,这就是手册中说的,“额外的一次排序”!,于是就会出现Using filesort,根据我以前写过的一文章,我再建立一个联合索引 room_number_id
在来分析一下
mysql> EXPLAIN SELECT id FROM testing WHERE room_number=1000 ORDER BY id ; +----+-------------+---------+------+----------------------------+----------------+---------+-------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------+----------------------------+----------------+---------+-------+------+--------------------------+ | 1 | SIMPLE | testing | ref | room_number,room_number_id | room_number_id | 4 | const | 1 | Using where; | +----+-------------+---------+------+----------------------------+----------------+---------+-------+------+--------------------------+ 1 row in set (0.00 sec)
现在Using filesort不见了。
总结一下:
1.一般有order by语句,在索引加得不当的情况下,都有可能出现Using filesort,这时候就要对SQL语句和索引进行优化了,但是,并不是说出现Using filesort就是个严重的问题,不是这样的,此次举的例子比较极端,几乎不太可能出现这么傻瓜的查询,优化和不优化,要看它是不是影响了业务性能。
2. 从上面可以看到联合索引,也可以叫多列索引,形如 key ('A1','A2','A3' ,'A4')等的,排序的思路一般是,先按照A1来排序,A1相同,然后按照A2排序,以此类推,这样对于(A1),(A1,A2),(A1,A2,A3)的索引都是有效的,但是对于(A2,A3)这样的索引就无效了。