【问题标题】:Mysql not use index over huge tableMysql 不在大表上使用索引
【发布时间】:2013-08-08 21:34:09
【问题描述】:

我有下一张桌子:

CREATE TABLE `test` (
 `fingerprint` varchar(80) COLLATE utf8_unicode_ci NOT NULL,
 `country` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
 `loader` int(10) unsigned NOT NULL,
 `date` date NOT NULL,
 `installer` int(10) unsigned DEFAULT NULL,
 `browser` varchar(5) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
 `version` varchar(5) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
 `os` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
 `language` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
 PRIMARY KEY (`fingerprint`, `date`),
 KEY `date_1` (`date`),
 KEY `date_2` (`date`,`loader`,`installer`,`country`,`browser`,`os`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

目前它包含 10M 条记录,并且每 2M 条记录/天会增加。

我的问题,为什么 MySQL 在下一个查询中使用“Using Where”:

explain select count(*) from test where date between '2013-08-01' and '2013-08-10'
1   SIMPLE  test    range   date_1,date_2   date_1  3       1601644 Using where; Using index

更新,为什么下一个问题有类型 - All 和 Using where then:

explain select * from test use key(date_1) where date between '2013-08-01' and '2013-08-10'
1 SIMPLE test ALL date_1 null null null 3648813 Using where

【问题讨论】:

  • 只是一个注释,你不需要date_1索引,date_2索引完全一样的功能
  • 是的,我知道,我添加 date_1 只是为了没有得到答案 - 使用 1 列索引
  • mysql fix Using where;的可能重复
  • 第二个问题确实是“mysql fix Using where;”的副本。 @TePort,尽管如此,请看我的更新。

标签: mysql indexing query-optimization


【解决方案1】:

确实使用索引。

上面写着:Using where; Using index。 “使用where”并不意味着完全扫描,它意味着它正在使用您提供的WHERE 条件。

1601644 数字也暗示了这一点:这意味着它预计读取大约 160 万条记录,而不是表中的全部 1000 万条记录,并且它与您每天约 200 万条的估计相关。

简而言之,它似乎做得很好,只是你要检索的数据很多。

不过,它也在读取表数据,看起来索引应该足够了。尝试将count(*) 更改为count(date),因此date 是整个查询中唯一提到的字段。如果你只得到Using index,那么它可能会更快。

【讨论】:

  • 实际上“使用索引”并不意味着它正在使用它来查找行(它也出现在全索引扫描中)。 type = range 表示它正在使用索引来查找匹配的行。
【解决方案2】:

您的查询不仅仅是“使用 where”,它实际上是“使用 where;使用索引”。这意味着该索引用于匹配您的WHERE 条件该索引用于执行键值查找。这是最好的情况,因为实际上该表从未被扫描过,查询只能使用索引来处理。

Here you can find 对您正在查看的输出含义的完整描述。


您的第二个查询仅显示“使用位置”通知。这意味着索引仅用于过滤行。必须从表中读取数据(没有“使用索引”通知),因为索引不包含所有行数据(您选择了所有列,但所选索引仅涵盖date)。如果您有一个覆盖索引(覆盖所有列),则可能会使用此索引。

【讨论】:

    猜你喜欢
    • 2015-08-13
    • 2022-12-31
    • 2014-04-07
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多