题外话:mysql
从深圳另外一个项目组交接了一个项目,这也是来到新公司后让我接手的第一个项目。在我接手的这段日子了,请公司测试部门的同事对一些主要的业务进行的压力测试。测试的结果并不理想。我仔细翻看了之前同事的逻辑以及数据库表的建立和sql语句的写法。发现有些sql并无很好的使用索引致使查询响应时间并不理想。我本身其实索引也使用的很差。正好趁着这个机会买了本《mysql高性能》书籍进行学习。因为书比较厚,只是针对索引部分学习了书本中的知识。在此整理一些知识点分享给和我有相似经验的人。web
正文:sql
索引是什么:数据库
索引是存储引擎用于快速找到记录的一种数据结构。在mysql中,存储引擎用相似的方法使用索引,其先在索引中找到对应的值,而后根据匹配的索引记录找到对应的数据行。mysql只能高效的使用索引的最左前缀列。建立一个包含两个列的索引,和建立两个只包含一列的索引是大不相同的。mysql中,索引是在存储引擎层而不是在服务器层现实的。因此,并无统一的索引标准。当人们谈论索引的时候,若是没有特别指明类型,那多半说的是B-Tree索引,它使用B-Tree数据结构来存储数据。服务器
说到这里特别强调了最左前缀列。那么在写sql的时候怎么样才能使用到这种B-Tree索引呢?下面总结出了几点须要注意的地方:数据结构
全值匹配:全值匹配指的是和索引中的全部列进行匹配性能
匹配最左前缀:即只使用索引的第一列。学习
匹配列前缀:也能够匹配某一列的值得开头部分。这里也只使用了索引的第一列。测试
匹配范围值:这里也是使用了索引的第一列。优化
精准匹配某一列并范围匹配另一列
只访问索引的查询:B-TREE一般能够支持“只访问索引的查询”,即查询只须要访问索引,而无需访问数据行。
那么也有些方式是不能使用到索引的,下面有些须要注意的地方:
若是不是按照索引的最左列开始查找,则没法使用索引
不能跳过索引中的列
若是查询中有某个列的范围查询,则其右边全部列都没法使用索引优化查找
书中别特强调了索引的顺序很重要。这些限制都和索引列的顺序有关。在优化性能的时候,可能须要使用相同的列但顺序不一样的索引来知足不一样类型的查询需求。
下面针对上面介绍的注意点给出一些本身测试的示例,来帮助你们理解:
CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`age` int(11) NOT NULL,
`number` int(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_person_name` (`name`,`age`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
mysql> EXPLAIN select * from person where age=10;
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | person | ALL | NULL | NULL | NULL | NULL | 4 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
经过上面的例子能够看到什么叫作最左前缀。