zoukankan      html  css  js  c++  java
  • 索引失效

    • where 条件中包含 or 时,可能会导致索引失效
      • 尽量避免使用 or 语句,可以根据情况使用 union in 等来代替,这两个语句的执行效率也比 or
      • 不同版本 MySQL,关于 or 走索引情况不一致,需要具体分析
      • MySQL 5.7 版本中,当 or 两边都是单列索引,索引生效
    • where 语句中索引列使用了负向查询,可能会导致索引失效
      • 负向查询包括:NOT!=<>!<!>NOT INNOT LIKE
      • 其中负向查询并不绝对会索引失效,这要看优化器判断,全表扫描或者走索引哪个成本低了
    • 索引字段可以为 null,使用 is null is not null,可能会导致索引失效
      • null 的列使索引/索引统计/值比较更加复杂,对 MySQL 来说更难优化
      • null MySQL 内部需要特殊处理,增加数据库处理记录的复杂性,同等条件下,表中有较多空字段的时候,数据库的处理性能会降低很多
      • null 值需要更多的存储空间,无论是表中还是索引中每行中的 null 的列都需要额外的空间来标识
      • null 的处理,只能采用 is null is not null,而不能使用 =、in、<、<>、!=、not in 这些符号操作
    • 在索引列上使用内置函数,一定会导致索引失效
      • 建议尽量在应用程序中进行计算和转换
    • 隐式类型转换导致的索引失效
      • 索引列 user_id 为 varchar 类型,不会命中索引,因为 MySQL 做了隐式类型转换,调用函数将 user_id 做了转换
      • select * from `user` where user_id= 12;
      • select * from `user` where CAST(user_id AS signed int) = 12;
    • 隐式字符编码转换导致的索引失效
      • 当两个表之间做关联查询时,如果两个表中关联的字段字符编码不一致的话,MySQL 可能会调用 CONVERT 函数,将不同的字符编码进行隐式转换从而达到统一;作用到关联的字段时,就会导致索引失效
      • Demo : select l.operator from `trade_log` l, `trade_detail` d where d.tradeid = l.tradeid and d.id = 4;
        • 其中 d.tradeid 字符编码为 utf8,而 l.tradeid 的字符编码是 utf8mb4
        • 因为 utf8mb4 utf8 的超集,所以 MySQL 在做转换时会用 CONVERT utf8 转成 utf8mb4;简单来看,就是 CONVERT 作用到了 d.tradeid 上,因此索引失效
      • Suggest :
        • 将关联的字段的字符编码统一
        • 若无法统一字符编码时,手动将 CONVERT 函数作用于关联式 = 的右侧,起到字符编码统一的目的;这里是强制将 utf8mb4 转为 utf8,注意:从超集向子集转换是有数据截断的风险的
          • select l.operator from `trade_log` l, `trade_detail` d where d.tradeid = CONVERT(l.tradeid USING utf8) and d.id = 4;
    • 对索引列进行运算,一定会导致索引失效
      • 运算符如:+、-、*、/ 等
      • Demo : select * from `user` where age - 1 = 10;
      • Suggest : 优化,将运算放在值上,或者在应用程序中算好
        • select * from `user` where age = 10 - 1;
    • like 通配符可能会导致索引失效
      • % 开头,索引失效
      • Suggest :
        • 去掉开头的 %
          • select * from `user` where `name` like '%';
        • 利用覆盖索引来名中索引
          • select name from `user` where `name` like '%%';

               

         

         

         

    • 联合索引中,违背最左匹配原则,一定会导致索引失效
    • MySQL 优化器的最终选择,不走索引
      • 即使完全符合索引生效的场景,考虑到实际数据量等原因,最终是否使用索引还要看 MySQL 优化器的判断;也可以在 SQL 中强制表明走哪个索引

       

    优化索引的建议:

    • 禁止在更新十分频繁,区分度不高的属性上建立索引
      • 更新会变更 B+树,更新频繁的字段建立索引会大大降低数据库性能
      • "性别"这种区分度不大的属性,建立索引是没有意义的,不能有效过滤数据,性能和全表扫描类似
    • 建立联合索引,必须把区分度高的字段放在前面
  • 相关阅读:
    数字类型和字符串类型
    python 基础-----数字,字符串,列表,字典类型简单介绍
    Pycharm快捷键的使用
    学习PYTHON之路, DAY 3
    购物车
    三级菜单
    模拟登录
    学习PYTHON之路, DAY 2
    学习PYTHON之路, DAY 1
    SSFOJ P1453 子序列(一) 题解
  • 原文地址:https://www.cnblogs.com/sebastian-tyd/p/13580165.html
Copyright © 2011-2022 走看看