【问题标题】:Mysql single table very slowmysql单表很慢
【发布时间】:2014-12-16 05:06:28
【问题描述】:

我在 MySQL 中有一个包含 50 多列的 InnoDB 表。表中有超过 500000 行。我只使用 DATETIME 列 (dt) 和 VARCHAR(245) 列 (code) 进行搜索。我为两列都创建了索引。

下面的查询很快:

SELECT COUNT(*) FROM TABLE WHERE `code` IN ('name1', 'name2') LIMIT 0,1000

这也很快:

SELECT COUNT(*) FROM TABLE WHERE `dt` BETWEEN '2014-01-01' AND  '2014-12-01' LIMIT 0,1000

但将两者结合起来需要几分钟:

 SELECT COUNT(*) FROM TABLE WHERE `code` IN ('name1', 'name2') AND `dt` BETWEEN '2014-01-01' AND  '2014-12-01' LIMIT 0,1000

有人能解释一下为什么最后一个查询需要很长时间,而前两个查询非常快吗?

最后一个查询的解释输出是:

Select type: Simple
Type: Range
possible keys: dt_index, code_index
key: ts_index

【问题讨论】:

  • 您有 2 个单独的索引还是一个组合索引? explain select ... 输出是什么?
  • 两个独立的索引。这是解释输出:选择类型:简单类型:范围可能的键:dt_index,code_index键:ts_index
  • 请将输出添加到问题中
  • 创建包含两列的复合索引。
  • 做到了!创建复合索引解决了这个问题。

标签: mysql


【解决方案1】:

MySQL 将只使用一个索引,并且由于您的两个索引中的任何一个都不包含这两个条件的值,因此它可能必须扫描大量行以找到匹配的 1000 个行。我认为如果您的日期间隔足够大,比如在 1970 年到 2015 年之间,它可能与第一次查询一样快。

要修复它,您可以添加一个涵盖两列的索引(并删除现在不需要的一列)

alter table TABLE add index dt_code_index (dt, code), drop index dt_index;

alter table TABLE add index code_dt_index (code, dt), drop index code_index;

【讨论】:

    【解决方案2】:

    这相当简单。我需要按照 xQbert 的建议向表中添加一个复合索引:

    create index fast_index ON traces (dt, code);
    

    现在所有 3 个查询都运行得很快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多