按照上述步骤即可建立一个哈希索引,对于哈希索引最后需要说明的是其查询方式,在进行查询时一定要带上查询的字符串与目标字段的等值比较,这是因为对于不同的数据,其哈希值可能是一样的,如:
select* from actor4 where hash_email=crc32('OZETIMfiqGCBAeEJuIp@yKIg.fnWxL') and email='OZETIMfiqGCBAeEJuIp@yKIg.fnWxL'; 2.4 覆盖索引覆盖索引指的是对于查询中使用的除去参与索引过滤扫描的所有字段将其加入到该查询所使用的索引尾部的索引。覆盖索引扫描的优点在于由于查询中所使用的所有字段都在同一索引的字段,因而在进行查询时只需要在索引中获取相关数据即可,而不需要回磁盘扫描相应的数据,从而避免了查询中最耗时的磁盘I/O读取。对于如下查询:
select a, b, c from t where a='a' and b='b';该查询中如果建立联合索引(a, b, c),那么这就是使用了覆盖扫描的索引,因为对于该查询,可以使用索引的前两个字段a和b根据where条件进行索引片的过滤,对过滤后的索引片直接在索引中读取a, b, c三个字段的值即可,而无需回表扫描。如下查询是一个索引覆盖扫描的实例:
SQL语句: select first_name, last_name from actor where first_name='qWhNIZqxcbD';
索引 first_name first_name, last_name耗时 1.12 0.01
可以看到,如果只使用first_name索引,其需要回磁盘读取last_name的值,从而返回最终数据,而对于(first_name, last_name)的联合索引,其不需要回磁盘扫描,因而耗时不到10ms。
2.5 三星索引三星索引指的是对于一个查询,设立了三个通用的索引条件满足的条件,建立的索引对于特定的查询每满足一个条件就表示该索引得到一颗星,当该索引得到三颗星时就表示该索引对于该查询是一个三星索引。三星索引是对于特定查询的最优索引,建立三星索引的条件如下:
取出所有的等值谓词的列(WHERE COL=…)作为索引开头的列;
将order by中的列加入到索引中;
将查询语句中剩余的列加入到索引中,将易变得列放到最后以降低更新成本。
比如对于如下的查询,索引(first_name, last_name, email)就是一个三星索引:
SELECT first_name, last_name, email FROM actor5 WHERE first_name = 'hawIPYaXHTSKHlTstt' ORDER BY last_name;仔细分析三星索引的创建过程可以发现如下规律:
覆盖等值谓词条件,如first_name,可以过滤大部分的索引片数据;
覆盖order by字段可以避免对结果集的排序,如last_name;
覆盖其余字段可以避免回磁盘读取数据,即使用了覆盖索引扫描,如email。
3. 不恰当的索引用法 3.1 无法使用索引的情形对索引字段使用MySQL函数(可以对等于号后的值使用,不能对字段使用)
select * from actor where lower(first_name)='rmqchuezjthp’;正确做法:
select * from actor where first_name='rMqChueZJThP';隐式字符串转换(这里license字段为一个varchar类型字段)
select * from actor where license=6535;正确做法:
select * from actor where license='6535';对索引字段使用数学表达式
select * from actor where hash_email + 2 = 4224712734;正确做法:
select * from actor where hash_email = 4224712732;