1.表结构,time1添加普通索引:
CREATE TABLE `time_table` (
`time1` INT(11) NULL DEFAULT NULL,
`time2` INT(11) NULL DEFAULT NULL,
INDEX `time1` (`time1`)
)
ENGINE=MyISAM
;
2.蠕虫复制创建200万条数据
insert into time_table select * from time_table
3.开始查询:time1有索引,time2没索引,数据200万
set profiling=1;
select * from time_table where time2=1111111;
select * from time_table where time1=1111111;
show profiles;
4.结果,加了索引反而变慢了:
重新反思,蠕虫复制的表的内容过于简单了,总共400百万条数据,200万条数据time1=11111,time2=11111,还有200万条数据,time1=22222,time2=22222,
重新制造200万条数据,先蠕虫复制400百万条数据,time2=1,然后新加字段time1(自增),在update time2=time1,
最终的表如下(time1是唯一索引):
查询时间分析,符合预期:
然后改成唯一索引,也符合预期:
但是依旧有问题:
为什么800万条数据,数据几乎一样(一半为111111,一半为2222)
添加索引的字段,反而查询更慢。
自己的猜想:数据一样,索引是不是作用效果几乎没有,但是因为有了索引,字段存储空间多了,查询慢了,纯属自己乱想,希望可以解答一二!
希望可以交流下,qq:2210170490
依照楼主的数据,我也造了400万数据:
id1创建索引
执行确实是id2谓词条件比较快:
mysql> select * from index_test where id1=11111;
2097152 rows in set (3.00 sec)
mysql> select * from index_test where id2=11111;
2097152 rows in set (2.32 sec)
id1的profile是这样的:
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000080 |
| checking permissions | 0.000014 |
| Opening tables | 0.000024 |
| init | 0.000033 |
| System lock | 0.000015 |
| optimizing | 0.000018 |
| statistics | 0.035408 |
| preparing | 0.000033 |
| executing | 0.000007 |
| Sending data | 2.963681 |
| end | 0.000021 |
| query end | 0.000015 |
| closing tables | 0.000020 |
| freeing items | 0.003474 |
| logging slow query | 0.000117 |
| cleaning up | 0.000072 |
+----------------------+----------+
可以看到id1耗时相对显著的是statistics,Sending data,主要集中在Sending data。
Sending data
The thread is reading and processing rows for a SELECT statement, and sending data to the client。
也就是说,id1=11111比id2=11111花费更多的时间在数据读取上。而id1上的是二级索引,用到该索引还有一个回表的花销,在这种数据基数小,索引的选择性就太差,这种情况不应该使用索引。
如果非要使用索引,就要避免回表,创建覆盖索引。
alter table index add index com_idx(id1,id2);
测试结果就可以看到id1=11111比id2=11111快了:
mysql> select * from index_test where id1=11111;
2097152 rows in set (1.71 sec)
mysql> select * from index_test where id2=11111;
2097152 rows in set (2.57 sec)
对应profile如下: