鲁安如 说:
今天研究了一下mysql的索引,颇有心得阿。通过实际操作 很明显看出来效果
刘玉军 说:
嗯,说来听听
鲁安如 说:
首先,我原来以为只要键了所引,查询速度就会快。我发现一个问题,我在状态status列键了所引,但查询速度还是很慢。如
select id,status,content,author,createtime,sourceType,questionType,servername,os,role,gmaccount from QUESTION where status<>1 and delflag<>2;
鲁安如 说:
后来查看资料发现 MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。后来我把语句改为
select id,status,content,author,createtime,sourceType,questionType,servername,os,role,gmaccount from QUESTION where status in (0,3) and delflag in(0,1);
鲁安如 说:
速度快些,但效果还是不如意,我想status 和delflag都有索引了,为什么速度还是上不去,又看资料说当我们执行查询的时候,MySQL只能使用一个索引。如果你有三个单列的索引,MySQL会试图选择一个限制最严格的索引。所以你键两个单列索引,在组合查询的时候,只有一个索引起作用。他能很快匹配出前面那个条件的记录,但后面那个条件的他还是要查询大量的记录
刘玉军 说:
嗯,再然后呢
鲁安如 说:
后来我把 status,delflag 连个索引删掉 建立 复合索引ALTER TABLE QUESTION ADD INDEX complex (delflag,status);
刘玉军 说:
这个时候速度就快了很多是吧
鲁安如 说:
这样性能就好了很多很多,我的QUESTION表里有几百万条数据,这样优化之后,速度明显提高。多列索引还有另外一个优点,它通过称为最左前缀(Leftmost Prefixing)的概念体现出来。当搜索条件是以下各种列的组合时,MySQL将使用complex索引:
status,delflag
status,
delflag
从另一方面理解,它相当于我们创建了(delflag,status)、delflag 以及 Status这些列组合上的索引。
鲁安如 说:
再说我如何知道 一条sql语句的执行效率
mysql> EXPLAIN select id,status,content,author,createtime,sourceType,questionType,servername,os,role,gmaccount from QUESTION where status<>1 and delflag<>2;
+----+-------------+----------+------+---------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+---------+-------------+
| 1 | SIMPLE | QUESTION | ALL | NULL | NULL | NULL | NULL | 1086113 | Us
我们可以看到 possible_keys =null说明没有可利用的索引,rows=1086113说明扫描了一百多万条记录
鲁安如 说:
以前执行这一条语句竟然花费了 24秒;优化后 46 rows in set (4.26 sec);有时候 46 rows in set (1.26 sec);
提高20倍;数据量越大越能体现出来 索引优化的好处
鲁安如 说:
我都疯了 24秒
刘玉军 说:
呵呵,小伙子不错,进步很多啊。
鲁安如 说:
我一直怀疑 数据库连接池有bug,机器到官方网站数据库的网络不好,其实还是程序优化的问题
刘玉军 说:
嗯,所以大多时候还是我们程序的问题,这个就是一个数据库的优化问题啊。
今天研究了一下mysql的索引,颇有心得阿。通过实际操作 很明显看出来效果
刘玉军 说:
嗯,说来听听
鲁安如 说:
首先,我原来以为只要键了所引,查询速度就会快。我发现一个问题,我在状态status列键了所引,但查询速度还是很慢。如
select id,status,content,author,createtime,sourceType,questionType,servername,os,role,gmaccount from QUESTION where status<>1 and delflag<>2;
鲁安如 说:
后来查看资料发现 MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。后来我把语句改为
select id,status,content,author,createtime,sourceType,questionType,servername,os,role,gmaccount from QUESTION where status in (0,3) and delflag in(0,1);
鲁安如 说:
速度快些,但效果还是不如意,我想status 和delflag都有索引了,为什么速度还是上不去,又看资料说当我们执行查询的时候,MySQL只能使用一个索引。如果你有三个单列的索引,MySQL会试图选择一个限制最严格的索引。所以你键两个单列索引,在组合查询的时候,只有一个索引起作用。他能很快匹配出前面那个条件的记录,但后面那个条件的他还是要查询大量的记录
刘玉军 说:
嗯,再然后呢
鲁安如 说:
后来我把 status,delflag 连个索引删掉 建立 复合索引ALTER TABLE QUESTION ADD INDEX complex (delflag,status);
刘玉军 说:
这个时候速度就快了很多是吧
鲁安如 说:
这样性能就好了很多很多,我的QUESTION表里有几百万条数据,这样优化之后,速度明显提高。多列索引还有另外一个优点,它通过称为最左前缀(Leftmost Prefixing)的概念体现出来。当搜索条件是以下各种列的组合时,MySQL将使用complex索引:
status,delflag
status,
delflag
从另一方面理解,它相当于我们创建了(delflag,status)、delflag 以及 Status这些列组合上的索引。
鲁安如 说:
再说我如何知道 一条sql语句的执行效率
mysql> EXPLAIN select id,status,content,author,createtime,sourceType,questionType,servername,os,role,gmaccount from QUESTION where status<>1 and delflag<>2;
+----+-------------+----------+------+---------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+---------+-------------+
| 1 | SIMPLE | QUESTION | ALL | NULL | NULL | NULL | NULL | 1086113 | Us
我们可以看到 possible_keys =null说明没有可利用的索引,rows=1086113说明扫描了一百多万条记录
鲁安如 说:
以前执行这一条语句竟然花费了 24秒;优化后 46 rows in set (4.26 sec);有时候 46 rows in set (1.26 sec);
提高20倍;数据量越大越能体现出来 索引优化的好处
鲁安如 说:
我都疯了 24秒
刘玉军 说:
呵呵,小伙子不错,进步很多啊。
鲁安如 说:
我一直怀疑 数据库连接池有bug,机器到官方网站数据库的网络不好,其实还是程序优化的问题
刘玉军 说:
嗯,所以大多时候还是我们程序的问题,这个就是一个数据库的优化问题啊。