我有一个有40000000行的表,我正在尝试优化我的查询,因为需要太长的时间。
首先,这是我的桌子:
创建表resume(
yearMonth字符(6)默认为空,
type字符(1)默认为空,
agen_o字符(5)默认为空,
tar字符(2)默认为空,
cve_ent字符(1)默认为空,
cve_mun字符(3)默认为空,
cve_regint(1)默认为空,
id_ope字符(1)默认为空,
ope_tip字符(2)默认为空,
ope_cve字符(3)默认为空,
cob_uint(9)默认为空,
tot_impbigint(15)默认为空,
)引擎=MyISAM默认字符集=latin1;
这是我的问题:
选择m.name_ope作为cve,
子字符串(r.yearMonth,5,2)作为周期,
计数(非重复(CONCAT(r.agen_ope,r.cve_ope))为num,
求和(当r.type='A'然后r.cob_ELSE 0结束时的情况)为tot_,
从简历r,媒体m
其中CONCAT(r.id_ope,子串(r.ope_cve,3,1))=m.ope_cve和
r.输入('C','D','E')和
子字符串(r.yearMonth,1,4)='2012'和
r.idøope='X'和
子串(r.ope_cve,1,2)IN(从catNac中选择cve_med,其中numero='0')
按子串分组(r.yearMonth,5,2),子串(r.ope_cve,3,1)
按子字符串排序(r.yearMonth,5,2),子字符串(r.ope_cve,3,1)
所以,我添加了一个包含以下字段的索引:idôope,yearMonth,agenôo,因为我有其他的查询在WHERE中有这个字段,按这个顺序
现在我的解释输出:
1主参考索引索引2 const 14774607使用where;使用文件排序
所以我添加了另一个带有yearMonth的索引ope_cve,但我仍然有“using filesort”。我如何优化这个?
谢谢

最佳答案

在不修改表结构的情况下,如果在yearMonth上有索引,则可以尝试执行以下操作:

SELECT m.name_ope AS cve,
SUBSTRING(r.yearMonth,5,2) AS period,
COUNT(DISTINCT(CONCAT(r.agen_ope,r.cve_ope))) AS num,
SUM(CASE WHEN r.type='A' THEN r.cob_u ELSE 0 END) AS tot_u,
FROM resume r, media m
WHERE CONCAT(r.id_ope,SUBSTRING(r.ope_cve,3,1))=m.ope_cve AND
r.type IN ('C','D','E') AND
r.yearMonth LIKE '2012%' AND
r.id_ope='X' AND
SUBSTRING(r.ope_cve,1,2) IN (SELECT cve_med FROM catNac WHERE numero='0')
GROUP BY r.yearMonth,SUBSTRING(r.ope_cve,3,1)

变化:
使用r.yearMonth LIKE '2012%'应该允许在where子句的那部分使用索引。
因为除了2012年,你每年都会过滤掉,所以你可以单独按GROUP BY r.yearMonth分组。
由于MySQL按ORDER BY排序,因此不需要GROUP BY子句,除非包含ORDER BY NULL

关于mysql - 使用Filesort-即使使用索引也无法避免,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12938731/

10-12 16:25