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

クエリを説明すると、最初のインデックスでは多くの行がスキャンされるのに対し、2 番目のインデックスには "ref: const" があり、数行しかスキャンされないことがわかります。しかし、なぜこれが起こるのかを理解したいと思います。

4

1 に答える 1

2

マニュアルに記載されているように:

テーブルに複数列のインデックスがある場合、オプティマイザーはインデックスの左端のプレフィックスを使用して行を検索できます。たとえば、 に 3 列のインデックスがある場合、 、、および(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)、最初の 2 つのクエリだけがインデックスを使用します。3 番目と 4 番目のクエリには、インデックス付きの列が含まれますが、の左端のプレフィックスではありませ(col2)ん。(col2, col3)(col1, col2, col3)

于 2012-05-30T00:04:30.527 に答える