0

我遇到了一个我想了解的有趣问题。我有一张桌子:

        `id` BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
        `user_id` BIGINT(20) unsigned NOT NULL,

        `followers_count` INT(10) unsigned NOT NULL DEFAULT 0,
        `friends_count` INT(10) unsigned NOT NULL DEFAULT 0,
        `statuses_count` INT(10) unsigned NOT NULL DEFAULT 0,
        `favourites_count` INT(10) unsigned NOT NULL DEFAULT 0,
        `listed_count` INT(10) unsigned NOT NULL DEFAULT 0,

        `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

        PRIMARY KEY (`id`)

我执行以下查询:

SELECT followers_count, friends_count, statuses_count, favourites_count, listed_count, UNIX_TIMESTAMP(DATE( created_at)) AS idFROM user_trackWHERE created_at>=DATE_SUB(NOW(),INTERVAL 14 DAY) AND user_id='1234567'

现在,有趣的部分:

1:使用该表上的以下索引,查询需要几分钟才能完成:

索引user_numbers( created_at, user_id, followers_count, friends_count, statuses_count, favourites_count, listed_count)

使用上述索引 1 解释查询:

id  select_type table       type    possible_keys   key             key_len     ref     rows    Extra
1   SIMPLE      user_track  range   user_numbers    user_numbers    12          NULL    1119318 Using where; Using index

2:但是,使用该表上的以下索引,它需要不到 200 毫秒:

索引user_report( user_id, id, created_at, followers_count, friends_count, statuses_count, favourites_count, listed_count)

使用上述索引 2 解释查询:

id  select_type table       type    possible_keys   key             key_len     ref     rows    Extra
1   SIMPLE      user_track  ref     user_report     user_report     8           const   1       Using where; Using index

通过解释查询,我看到第一个索引导致扫描很多行,而第二个索引具有“ref: const”并且只扫描了几行。但我想了解为什么会发生这种情况。

4

1 回答 1

2

手册所述:

如果表有一个多列索引,优化器可以使用索引的任何最左边的前缀来查找行。例如,如果您在 上具有三列索引,则您在、和(col1, col2, col3)上具有索引搜索功能。(col1)(col1, col2)(col1, col2, col3)

如果列不构成索引的最左前缀,则 MySQL 无法使用索引执行查找。假设您有SELECT此处显示的语句:

SELECT * FROM tbl_name WHERE col1=val1;
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

SELECT * FROM tbl_name WHERE col2=val2;
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;

如果 上存在索引(col1, col2, col3),则只有前两个查询使用该索引。第三和第四个查询确实涉及索引列,(col2)(col2, col3)不是(col1, col2, col3).

于 2012-05-30T00:04:30.527 回答