mysql索引过多为什么会慢_mysql – 为什么索引使这个查询更慢?
摘要
問題是由于b-trees的性質,字段不適合索引.
說明
假設你有一張表有500,000個擲硬幣的結果,其中拋擲是1(頭)或0(尾):
CREATE TABLE toss (
id int NOT NULL AUTO_INCREMENT,
result int NOT NULL DEFAULT '0',
PRIMARY KEY ( id )
)
select result, count(*) from toss group by result order by result;
+--------+----------+
| result | count(*) |
+--------+----------+
| 0 | 250290 |
| 1 | 249710 |
+--------+----------+
2 rows in set (0.40 sec)
如果你想選擇一個折騰(隨機)折騰尾巴,那么你需要搜索你的桌子,挑選一個隨機的起始位置.
select * from toss where result != 1 limit 123456, 1;
+--------+--------+
| id | result |
+--------+--------+
| 246700 | 0 |
+--------+--------+
1 row in set (0.06 sec)
explain select * from toss where result != 1 limit 123456, 1;
+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | toss | ALL | NULL | NULL | NULL | NULL | 500000 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+
您看到您基本上按順序搜索所有行以查找匹配項.
如果在折騰字段上創建索引,則索引將包含兩個值,每個值大約有250,000個條目.
create index foo on toss ( result );
Query OK, 500000 rows affected (2.48 sec)
Records: 500000 Duplicates: 0 Warnings: 0
select * from toss where result != 1 limit 123456, 1;
+--------+--------+
| id | result |
+--------+--------+
| 246700 | 0 |
+--------+--------+
1 row in set (0.25 sec)
explain select * from toss where result != 1 limit 123456, 1;
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | toss | range | foo | foo | 4 | NULL | 154565 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
現在您搜索的記錄較少,但搜索時間從0.06增加到0.25秒.為什么?因為順序掃描索引實際上比順序掃描表的效率低,對于給定鍵具有大量行的索引.
我們來看看這個表上的索引:
show index from toss;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| toss | 0 | PRIMARY | 1 | id | A | 500000 | NULL | NULL | | BTREE | |
| toss | 1 | foo | 1 | result | A | 2 | NULL | NULL | | BTREE | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
PRIMARY索引是一個很好的索引:有500,000行,有500,000個值.安排在BTREE中,您可以根據ID快速識別單行.
foo索引是一個錯誤的索引:有500,000行,但只有2個可能的值.對于BTREE來說,這幾乎是最糟糕的情況 – 搜索索引的所有開銷,仍然需要搜索結果.
總結
以上是生活随笔為你收集整理的mysql索引过多为什么会慢_mysql – 为什么索引使这个查询更慢?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黑苹果uhd630黑屏_求助各位图吧大佬
- 下一篇: centos安装mysql5.6系统崩溃