連合インデックス(a,b)は、MySQLインデックスに対する印象を覆す
5174 ワード
一、表構造
二、一意性基数
update_timeの選択性:1845933/1907609.to_f=0.9676684268107353近1
publish_statusの選択性:2/1907609.to_f=1.0484328811617055 e-06 0に近い
三、(a,b)インデックスを確立し、それぞれaクエリー、bクエリー、(a,b)クエリー、(b,a)クエリー、統計結果に基づいて
普通の道を歩かないで、私は選択性の低いインデックスの第一位を選んだ.
索引の作成
aクエリーによる
平均クエリー時間:
インデックス(a,b)のa部分は理論的に用いることができる.
bクエリーによる
平均クエリー時間:
bをクエリーするときは、理論的にインデックスは使いません.どうしてここに??
(a,b)クエリによる
平均クエリー時間:
理論上の予想に合致する.
(b,a)クエリによる
平均クエリー時間:
理論的には、ここで(a,b)のa部分しか使えないのに、どうしてこんなに速いの??
結論:
1、理論的にインデックスは順序に敏感ですが、MySQLのクエリー・オプティマイザはwhere句の条件順序を自動的に調整して適切なインデックスを使用します.
2、選択性の高いカラムをインデックスの先頭に置きます.シーンによっては、この経験法則は完全に正確ではありません.一部のシーンでは、実行頻度が最も高いクエリーに基づいてインデックス列の順序を調整する必要がある場合があります.
リファレンス
http://www.programering.com/a/MTMwAzMwATM.html
CREATE TABLE `cd_happy_for_ni_deals` (
`id` int(11) NOT NULL DEFAULT '0',
`update_time` datetime DEFAULT NULL COMMENT ' ',
`publish_status` int(11) NOT NULL DEFAULT '4' COMMENT ' ',
KEY `idx_of_publish_status_update_time` (`publish_status`,`update_time`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
二、一意性基数
mysql> select count(distinct(update_time)) from cd_happy_for_ni_deals;
+------------------------------+
| count(distinct(update_time)) |
+------------------------------+
| 1845933 |
+------------------------------+
1 row in set (4.68 sec)
mysql> select count(distinct(publish_status)) from cd_happy_for_ni_deals;
+---------------------------------+
| count(distinct(publish_status)) |
+---------------------------------+
| 2 |
+---------------------------------+
1 row in set (1.76 sec)
mysql> select count(id) from cd_happy_for_ni_deals;
+-----------+
| count(id) |
+-----------+
| 1907609 |
+-----------+
1 row in set (0.00 sec)
update_timeの選択性:1845933/1907609.to_f=0.9676684268107353近1
publish_statusの選択性:2/1907609.to_f=1.0484328811617055 e-06 0に近い
三、(a,b)インデックスを確立し、それぞれaクエリー、bクエリー、(a,b)クエリー、(b,a)クエリー、統計結果に基づいて
普通の道を歩かないで、私は選択性の低いインデックスの第一位を選んだ.
索引の作成
mysql> alter table cd_happy_for_ni_deals add index `idx_of_publish_status_update_time` (`publish_status`, `update_time`, `id`);
Query OK, 0 rows affected (14.69 sec)
Records: 0 Duplicates: 0 Warnings: 0
aクエリーによる
mysql> explain select SQL_NO_CACHE id, publish_status from cd_happy_for_ni_deals where publish_status = 4 \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: cd_happy_for_ni_deals
type: ref
possible_keys: idx_of_publish_status_update_time
key: idx_of_publish_status_update_time
key_len: 4
ref: const
rows: 964056
平均クエリー時間:
mysql> select SQL_NO_CACHE count(id) from cd_happy_for_ni_deals where publish_status = 4 \G;
*************************** 1. row ***************************
count(id): 1858081
1 row in set (0.69 sec)
インデックス(a,b)のa部分は理論的に用いることができる.
bクエリーによる
mysql> explain select SQL_NO_CACHE id, publish_status from cd_happy_for_ni_deals where update_time = '2014-05-17 23:00:48' \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: cd_happy_for_ni_deals
type: index
possible_keys: NULL
key: idx_of_publish_status_update_time
key_len: 17
ref: NULL
rows: 1928113
平均クエリー時間:
mysql> select SQL_NO_CACHE count(id) from cd_happy_for_ni_deals where update_time = '2014-05-17 23:00:48' \G;
*************************** 1. row ***************************
count(id): 1
1 row in set (1.06 sec)
bをクエリーするときは、理論的にインデックスは使いません.どうしてここに??
(a,b)クエリによる
mysql> explain select SQL_NO_CACHE id, publish_status from cd_happy_for_ni_deals where publish_status = 4 and update_time = '2014-05-17 23:00:48' \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: cd_happy_for_ni_deals
type: ref
possible_keys: idx_of_publish_status_update_time
key: idx_of_publish_status_update_time
key_len: 13
ref: const,const
rows: 1
Extra: Using where; Using index
1 row in set (0.01 sec)
平均クエリー時間:
mysql> select SQL_NO_CACHE count(id) from cd_happy_for_ni_deals where publish_status = 4 and update_time = '2014-05-17 23:00:48' \G;
*************************** 1. row ***************************
count(id): 1
1 row in set (0.00 sec)
理論上の予想に合致する.
(b,a)クエリによる
mysql> explain select SQL_NO_CACHE id, publish_status from cd_happy_for_ni_deals where update_time = '2014-05-17 23:00:48' and publish_status = 4 \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: cd_happy_for_ni_deals
type: ref
possible_keys: idx_of_publish_status_update_time
key: idx_of_publish_status_update_time
key_len: 13
ref: const,const
rows: 1
Extra: Using where; Using index
1 row in set (0.00 sec)
平均クエリー時間:
mysql> select SQL_NO_CACHE count(id) from cd_happy_for_ni_deals where update_time = '2014-05-17 23:00:48' and publish_status = 4 \G;
*************************** 1. row ***************************
count(id): 1
1 row in set (0.00 sec)
理論的には、ここで(a,b)のa部分しか使えないのに、どうしてこんなに速いの??
結論:
1、理論的にインデックスは順序に敏感ですが、MySQLのクエリー・オプティマイザはwhere句の条件順序を自動的に調整して適切なインデックスを使用します.
2、選択性の高いカラムをインデックスの先頭に置きます.シーンによっては、この経験法則は完全に正確ではありません.一部のシーンでは、実行頻度が最も高いクエリーに基づいてインデックス列の順序を調整する必要がある場合があります.
リファレンス
http://www.programering.com/a/MTMwAzMwATM.html