前言:
当一条SQL语句执行速度较慢时,我们想到的第一件事就是给条件列加上索引,但是索引并不是适用于所有的字段,添加索引甚至可能导致检索速度变慢。什么样的数据列适合加索引呢?这是一个值得考虑的问题。
开发规范:
强制 页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决
说明:索引文件具有B+Tree的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引
相信大多数人对于上面的规范都有所了解。但是索引的选择性问题更加隐蔽,在某些条件下不适合建立索引。
索引选择性陷阱
#
上表除了主键之外,其他几个字段也都建立了相应的索引:
MySQL中的索引组织形式:B+tree
主键上建立聚簇索引(数据按照索引的顺序排列和组织)
name字段的索引是非聚集索引,通过对应的编号或者地址再到聚簇索引中去查找对应的列数据。
头匹配索引也未必会使用
如上图的1,在模糊查询时即使在mobile上建立了索引,但是由于符合规则的数据数量较多,因此不走索引反而速度更快,查询优化器经过优化之后决定不走索引。
1和2都是索引的选择性过差,索引的命中率过高,因此走了全表扫描
案例常见
解决索引选择性差的方法
1 通过组合索引来提高选择性(业务相关,可能不能使用)
2 引入搜索引擎 如Es或者Solr(更换数据源) 解决全文检索问题
例如将护士表导入ElasticSearch,Es基于分片多线程检索,解决查询慢的问题 (引入问题:使得架构复杂度提升,MySQL和Es的数据一致性问题)
3 强制使用索引(有时候会效果)
explain select * from question force index(answer) where answer = ‘A’
4 增加缓存,提高全表扫描的速度(钞能力)