我有一个非常大的表,下面的代码需要 990 秒。去完成。 bdate
和 itype
已建立索引。我还需要优化/更改哪些内容?
SELECT s, count(*) as total
FROM `mt_ex_15`
WHERE bdate > '2014-10-01' and bdate < '2014-11-01'
and itype = '3'
group by s
order by total desc
编辑:这是解释
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE mt_ex_15 ref itype,bdate,s itype 2 const 44157686 Using where; Using temporary; Using filesort
编辑:我认为我需要优化我的数据库或 my.cnf,因为即使下面的查询也花费了 40 秒。
SELECT count(*) as total
FROM `mt_ex_15`
WHERE bdate > '2015-02-01' and bdate < '2015-03-01'
解释如下:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE mt_ex_15 range bdate bdate 3 NULL 4494019 Using where; Using index
最佳答案
对于此查询:
SELECT s, count(*) as total
FROM `mt_ex_15`
WHERE bdate > '2014-10-01' and bdate < '2014-11-01' and itype = '3'
group by s
order by total desc
最佳索引是mt_ex_15(itype, bdate, s)
。引擎应该能够充分利用 where
子句的索引。此外,这是一个覆盖索引,因此该查询不需要触及原始数据。
如果您有所有可用“s”值的列表,您可以将其作为相关子查询来执行:
select s.*,
(select count(*)
from mt_ex_15 m
where m.s = s.s and m.itype = 3 and m.bdate > '2014-10-01' and m.bdate < '2014-11-01'
) total
from s
having total > 0 -- using a convenient MySQL extension
order by total desc;
此查询的最佳索引是 mt_ex_15(s, itype, bdate)
。
注意:如果itype
确实是一个整数,则应该删除常量周围的引号。它们具有误导性。
关于MySQL 查询需要很长时间才能返回一个巨大的表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29806847/