在mysql 实际sql查询数据执行中,很多情况会导致索引实效,下面我从 建立索引,索引失效情况,推荐索引建立情况三个部分说一下sql索引实效和sql索引优化
 
1.索引的建立
(1)为了加快sql 查询的速度,所以根据需要建立索引。当表数据少于几千行可以不建立索引。
(2)索引的建议与查询条件一致,如果没有对应查询条件,不建立索引。
(3)建立索引,索引子段顺序建议要与查询条件一致,排序也一致,按照最左前缀原则,依此查询。
(4)不建立索引 筛选条件最好能直接排除筛选内容多的情况,比如 是否,如果查询条件是的数据,而且最多建立索引没有太大意义,放到查询条件最后
(5)使用最小子段建立索引,比如是否就用tinyint 1,值为0,1,长度越小越好
(6)只针对前缀索引,有文本索引建议指定长度
(7)创建索引对应列不建议为null,可以有空字符串 (B-Tree不影响索引)
(8)唯一约束本身就是索引
(9)写多,读少的情况下,少建立索引,一般最多5个。读多的优先建立索引
 
2. 索引失效情况
(1)使用 != / not in / NOT EXISTS
(2)使用函数,比如 时间转换
(3)查询条件 和索引位置不一致,比如 INDEX (a, b, c),查询 WHERE b = 1 AND c = 2   跳过 a
(4)索引列参与表达式运算 ,比如 age * 2 > 40
(5)隐式类型转换,比如 字符串转数字,或者数字转字符串
(6)隐式字符集/排序规则转换 比如条件中有2个字符集 不一样,一个utf8 一个utf8mb4
 (7) 模糊查询 LIKE 以 % 开头
(8) OR 连接的条件, a=1 or b=2 如果a有索引b没有,则可能全表扫描
(9)筛选条件中 IS NULL / IS NOT NULL,可能会失效
(10)  排序/分组方向与索引不一致, order by 与定义索引排序不一致
(11)ORDER BY 与 WHERE 用的不是同一索引
(12) UNION 与 UNION ALL,部分情况下
 
3. 优化
(1)索引 (a) 和 (a,b) 中,(a) 是冗余的(最左前缀已覆盖)
(2)子查询列可能为 NULL → 必须用 NOT EXISTS(或 LEFT JOIN ... WHERE 主键 IS NULL),否则 NOT IN 结果错误。
子查询结果集可能很大 → 倾向 NOT EXISTS。
固定值列表(NOT IN (1,2,3))→ 保持 NOT IN,无需改
(3)B+Tree 索引是有序的,适合:
等值 =
范围 > < BETWEEN
前缀 LIKE 'x%'