在了解了索引的基础知识及B+树索引的原理后(如需复习请点这里),这一节咱们了解一下有哪些建索引的原则,来指导咱们去建索引。html
咱们可能听一些数据库方面的专业人士说过:“把 Where 条件里面的列都建上索引”,从而给每一个列给每一个列建独立的索引,这个理解是很是错误的。mysql
若是 Where 条件里有多种组合的查询条件,能够尝试建联合索引来减小索引数量,同时提高查询性能。sql
普通索引查到主键后,回到主键索引搜索的过程,称为回表。数据库
当使用普通索引查询时,普通索引有咱们所需结果的全部信息(字段),就能够直接提供查询结果,而不须要回表。也就是说,在这个查询里,索引已经被“覆盖了”查询需求,称为覆盖索引。性能优化
mysql> create table T ( ID int primary key, k int NOT NULL DEFAULT 0, s varchar(16) NOT NULL DEFAULT '', index k(k)) engine=InnoDB; select ID from T where k between 3 and 5
上面的例子中,k索引树上已经包括了ID的值,就不须要回表了。性能
因为覆盖索引能够减小树的搜索次数,显著提高查询性能,因此使用覆盖索引是一个经常使用的性能优化手段。优化
在使用覆盖索引时,要注意若是须要返回的字段较多,就要权衡空间和时间。由于覆盖索引要覆盖较多字段就须要更多的空间。code
假设咱们有2个字段,例如身份证号和地址,如今有三种查询需求:按身份证号查询、按地址查询,以及按身份证号和地址查询。htm
若是每种须要都要建立一个索引,就显得有利浪费。blog
从上一篇文章里,咱们了解到B+树的特色是有序的,所以咱们能够只建立两个索引即知足上面的三种需求,分别是(身份证号,地址)和(地址)。这就是B+树索引的“最左前缀”原则。
在创建联合索引的时候,如何安排索引内的字段顺序:
有时候须要索引很长的字符列,这会让索引变得大且慢。一种策略是模拟哈希索引。
一般能够索引开始的部分字符,这样能够大大节约索引空间,从而提升索引效率。但这样也会下降索引的选择性。
索引的选择性指,不重复的索引值(也称为基数,cardinality)和数据表的记录总数(T)的比值,范围从1/T到1之间。
假设有个订单表,其中有包括城市名称的字段(city,且城市名称为英文),下面来介绍一下如何肯定前缀索引的长度。
mysql> create table orders ( ID int primary key, city varchar(16) NOT NULL )engine=InnoDB;
一种方法是计算完整列的选择性,并使前缀的选择性接近于完整列的选择性。
计算完整列的选择性:
mysql> SELECT COUNT(DISTINCT city)/COUNT(*) FROM orders;
在同一个查询中计算不一样前缀长度的选择性:
mysql> SELECT COUNT(DISTINCT LEFT(city, 3))/COUNT(*) AS sel3, COUNT(DISTINCT LEFT(city, 4))/COUNT(*) AS sel4, COUNT(DISTINCT LEFT(city, 5))/COUNT(*) AS sel5, COUNT(DISTINCT LEFT(city, 6))/COUNT(*) AS sel6, COUNT(DISTINCT LEFT(city, 7))/COUNT(*) AS sel7 FROM orders;
建立前缀索引的方法:
mysql> ALTER TABLE orders ADD KEY (city(7));
在联合索引中,索引列的顺序是按照从左到右逐列进行排序的。所以索引能够按照升序或降序进行扫描,以知足精确符合列顺序的 ORDERY BY、GROUP BY 和 DISTINCT 等子句的查询需求。
所以联合索引的列顺序很重要。
如何选择索引的列顺序有一个经验法则:将选择性最高的列放到索引最前列。
这个经验法则在某些场景下有用,但可能在另外场景下,可能就没效了,这要根据具体状况进行分析。