我有一个有40000000行的表,我正在尝试优化我的查询,因为需要太长的时间。
首先,这是我的桌子:
创建表resume
(yearMonth
字符(6)默认为空,type
字符(1)默认为空,agen_o
字符(5)默认为空,tar
字符(2)默认为空,cve_ent
字符(1)默认为空,cve_mun
字符(3)默认为空,cve_reg
int(1)默认为空,id_ope
字符(1)默认为空,ope_tip
字符(2)默认为空,ope_cve
字符(3)默认为空,cob_u
int(9)默认为空,tot_imp
bigint(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/