索引选择性
索引选择性
对索引列和字符串前缀长度,都参考选择性(Selectivity)这个指标来确定:选择性定义为不重复的索引值和数据总记录条数的比值,其选择性越高,那么索引的查询效率也越高,譬如对于性别这种参数,建立索引根本没有意义。
Index Selectivity = Cardinality / #T
显然选择性的取值范围为 (0, 1]
,选择性越高的索引价值越大,这是由
SELECT count(DISTINCT(title))/count(*) AS Selectivity FROM titles;
区分度:count(distinct col)/count(*)
。
区分度是一个介于
覆盖索引
覆盖索引指的是对于查询中使用的除去参与索引过滤扫描的所有字段将其加入到该查询所使用的索引尾部的索引。覆盖索引扫描的优点在于由于查询中所使用的所有字段都在同一索引的字段,因而在进行查询时只需要在索引中获取相关数据即可,而不需要回磁盘扫描相应的数据,从而避免了查询中最耗时的磁盘
select a, b, c from t where a='a' and b='b';
该查询中如果建立联合索引
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;
insert into T values(100,1, 'aa'),(200,2,'bb'),(300,3,'cc'),(500,5,'ee'),(600,6,'ff'),(700,7,'gg');

如果直接执行 select * from T where k between 3 and 5
,那么会经历以下步骤:
- 在
k 索引树上找到k=3 的记录,取得ID = 300 ; - 再到
ID 索引树查到ID=300 对应的R3 ; - 在
k 索引树取下一个值k=5 ,取得ID=500 ; - 再回到
ID 索引树查到ID=500 对应的R4 ; - 在
k 索引树取下一个值k=6 ,不满足条件,循环结束。 - 在这个过程中,回到主键索引树搜索的过程,我们称为回表。可以看到,这个查询过程读了
k 索引树的3 条记录,回表了两次。在这个例子中,由于查询结果所需要的数据只在主键索引上有,所以不得不回表。
select ID from T where k between 3 and 5
,这时只需要查覆盖索引
。
三星索引
三星索引指的是对于一个查询,设立了三个通用的索引条件满足的条件,建立的索引对于特定的查询每满足一个条件就表示该索引得到一颗星,当该索引得到三颗星时就表示该索引对于该查询是一个三星索引。三星索引是对于特定查询的最优索引,建立三星索引的条件如下:
- 取出所有的等值谓词的列
(WHERE COL=…)
作为索引开头的列; - 将
ORDER BY 中的列加入到索引中; - 将查询语句中剩余的列加入到索引中,将易变得列放到最后以降低更新成本。
譬如对于如下的查询,索引 (first_name, last_name, email)
就是一个三星索引:
SELECT first_name, last_name, email FROM user WHERE first_name = 'aa' ORDER BY last_name;
三星索引的创建过程可以发现如下规律:
- 覆盖等值谓词条件,如
first_name ,可以过滤大部分的索引片数据; - 覆盖
order by 字段可以避免对结果集的排序,如last_name; - 覆盖其余字段可以避免回磁盘读取数据,即使用了覆盖索引扫描,如
email 。