现在的位置: 首页 > 综合 > 正文

MySql 索引

2013年01月13日 ⁄ 综合 ⁄ 共 3489字 ⁄ 字号 评论关闭

1.DISTINCT关键字

   从explain语句来看,加上DISTINCT的结局是mysql会创建临时表来过滤重复行!

mysql> explain SELECT DISTINCT owner FROM pet;
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra           |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------+
|  1 | SIMPLE      | pet   | ALL  | NULL          | NULL | NULL    | NULL |    8 | Using temporary |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------+
1 row in set (0.01 sec)

mysql> explain SELECT  owner FROM pet;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | pet   | ALL  | NULL          | NULL | NULL    | NULL |    8 |       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+

mysql> explain select value2 from test where   value1>0 order by value2;
+----+-------------+-------+-------+---------------+--------+---------+------+------+-----------------------------+
| id | select_type | table | type  | possible_keys | key    | key_len | ref  | rows | Extra                       |
+----+-------------+-------+-------+---------------+--------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | test  | range | value1        | value1 | 4       | NULL |    1 | Using where; Using filesort |
+----+-------------+-------+-------+---------------+--------+---------+------+------+-----------------------------+
1 row in set

mysql> explain select id from test where   value1>0 order by id;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | test  | index | value1        | PRIMARY | 4       | NULL |    3 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+

mysql> explain select * from test where   value1>0 order by id;
+----+-------------+-------+-------+---------------+--------+---------+------+------+-----------------------------+
| id | select_type | table | type  | possible_keys | key    | key_len | ref  | rows | Extra                       |
+----+-------------+-------+-------+---------------+--------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | test  | range | value1        | value1 | 4       | NULL |    1 | Using where; Using filesort |
+----+-------------+-------+-------+---------------+--------+---------+------+------+-----------------------------+

employee数据库中salaries表的建索引速度比较,emp_no和salary列相差八倍之多,总共280w记录左右。

原因是emp_no是单调递增的插入(基本每十个记录使用相同的emp_no,相比salary单调一些),而salary列插入时则不是单调的,频繁移动的结局就是创建所以速度变慢。

emp_no的选择性为0.1, salary为0.03. 理论上创建salary索引之后,插入速度就会比创建钱慢8倍以上。

mysql> create index emp_no on salaries (emp_no);
Query OK, 2844047 rows affected (37.34 sec)
Records: 2844047  Duplicates: 0  Warnings: 0

mysql> create index salary on salaries (salary);
Query OK, 2844047 rows affected (4 min 3.98 sec)
Records: 2844047  Duplicates: 0  Warnings: 0

salary列上有索引和无索引的速度相差40倍之巨,可能我插入的这条记录需要btree移动的太多了,但也可见索引建在单调的key上是很重要的。选择性太小的列也没必要建

索引,一个是查找时效果不好,另外一个是导致维护索引的成本太高。

有salary单列索引的情况下

mysql> insert into salaries ( emp_no, salary,from_date, to_date) values (20541,
1178,'1992-08-23', '1993-08-23');
Query OK, 1 row affected (2.08 sec)

删除salary上所以之后
mysql> insert into salaries ( emp_no, salary,from_date, to_date) values (20541,6
1178,'1992-08-23', '1993-08-23');
Query OK, 1 row affected (0.06 sec)

抱歉!评论已关闭.