mysql优化参考(二)-索引

参考:https://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html

 

索引(Indexs)

 

一、作用(轻定义):索引用于快速查找具有特定列值的行。没有索引,MySQL必须从第一行开始,然后通读整个表以找到相关的行。表越大,花费时间越长。如果表中有相关??列的索引,MySQL可以快速确定要在数据文件中间查找的位置,而不必查看所有数据。这比顺序读取每一行要快得多。

二、数据结构:B+树(官方写的是B树)-与二叉树不同:多个分叉

  • 参考:https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_b_tree
  • 与存储引擎的关系:InnoDB、MyIsAM,Memory也可以使用(但一般使用哈希表会更合适)。B树更适合范围查询,哈希表更适合值匹配

三、mysql具体使用索引做什么

  • WHERE中作为查询条件快速查找与子句匹配的行

  • 从考虑中消除行(possible_keys中有多个可考虑的索引的时候,mysql通常会选择最少行数的索引)。最具 选择性的(https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_selectivity)索引)。

  • 如果表具有多列索引,那么优化器可以使用索引的任何最左前缀来查找行。举例来说,如果你有一个三列的索引 (col1, col2, col3),你有索引的搜索功能(col1), (col1, col2)以及(col1, col2, col3)有关更多信息,请参见 第8.3.5节“多列索引”(https://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html)。【这个指的应该是组合索引,会使用最左匹配,优先用组合索引最左的进行匹配】

  • 执行联接时从其他表中检索行。如果声明相同的类型和大小,MySQL可以更有效地在列上使用索引。在这种情况下, VARCHAR与 CHAR被认为是相同的,如果它们被声明为相同的大小。例如, VARCHAR(10)和 CHAR(10)是相同的大小,但是 VARCHAR(10)和 CHAR(15)不是。【应该是指用于连接两个表的字段大小一致】

    对于非二进制字符串列之间的比较,两个列应使用相同的字符集。例如,将一utf8列与一 latin1进行比较会排除使用索引。

    如果不能不通过转换直接比较值,则比较不同的列(例如,将字符串列与时间或数字列进行比较)可能会阻止使用索引。对于给定的值,如1 在数值列,它可能比较等于在字符串列,例如任何数量的值 ‘1‘‘ 1‘, ‘00001‘,或‘01.e1‘这排除了对字符串列使用任何索引的可能性。

  • 查找特定索引列MIN()或 MAX()key_col这由预处理器优化,该预处理器检查您是否正在 索引中之前出现的所有关键部分上使用在这种情况下,MySQL为每个表达式或 表达式执行一次键查找,并将其替换为常量。如果所有表达式都用常量替换,查询将立即返回。例如: WHERE key_part_N = constantkey_colMIN()MAX()

    SELECT MIN(key_part2),MAX(key_part2)
      FROM tbl_name WHERE key_part1=10;
  • 如果排序或分组是在可用索引的最左前缀(例如上完成的,则对表进行排序或分组 如果所有关键部分后面都有,则按相反顺序读取密钥。请参见 第8.2.1.14节“按优化排序”和 第8.2.1.15节“按优化分组”。 ORDER BY key_part1key_part2DESC

  • 在某些情况下,可以优化查询以检索值而无需查询数据行。(为查询提供所有必要结果的索引称为 覆盖索引。)如果查询仅从表中使用某些索引中包含的列,则可以从索引树中检索所选值,以提高速度:

    SELECT key_part3 FROM tbl_name
      WHERE key_part1=1

 

附录:

  回表:比如过滤条件是name,查询的字段是age,扫描b+树之后获取到的主键id,再通过主键ID去扫描出数据

  索引覆盖:查询的字段直接在索引中,不需要回表查询;以回表的例子来看,我们把查询的字段改为主键id,那就不需要再扫描数据

  最左匹配:一般用于优化过滤,优先过滤数据较少的表

  组合索引:结合最左匹配,一样可以通过优先级进行优化。低版本中查询的时候根据组合索引的字段过滤顺序会影响效率,高版本之后就没有影响了

  索引下推:一般是指组合索引中,两个过滤条件命中的情况下,会一次过滤,而不是多次回表过滤

mysql优化参考(二)-索引

上一篇:sql算法练习——查找入职员工时间排名倒数第三名


下一篇:PostgreSQL - psql的使用与退出