索引

作者: szn好色仙人 | 来源:发表于2019-12-14 15:51 被阅读0次
    • 索引的作用类似于指向表的行的指针,允许查询时快速确定哪些行匹配where子句中的条件,以提高查询效率

    • 不必要的索引会带来列插入、更新、删除时的负担,因为索引的维护是需要成本的

    B树索引特性

    • B树索引支持=, >, >=, <, <=, between

    • 支持常量字符串开头的like匹配

    • 所有的值都是按顺序存储的,并且每一个叶子页到根的距离相等

    • 很适合范围查找

    • 大部分索引都是B树索引

    哈希索引特征

    • 哈希索引仅支持相等性测试(=, <=>in())
    • 整个键都必须被使用
    create table t(i bigint auto_increment primary key, name varchar(20), key using hash(name))
    --建立哈希索引
    
    create table t1(i bigint auto_increment primary key, name varchar(20), hName bigint, index(hName))
    --在B-Tree基础上实现哈希索引,哈希值需要自己维护
    

    独立的列

    • 如果查询的列不是独立的,则不会使用索引。独立的列是指索引列不能是表达式的一部分,也不能是函数的参数
    select * from t where id + 1 = 5;
    select * from t where hex(id) = 5;
    --上述查询无法使用id列上的索引
    

    前缀索引

    • 前缀索引有利于减少索引文件的大小,从而节省磁盘空间,并且加快insert的速度
    • 对于字符串列(char, varchar, binary, varbinary, text, blob),可以使用前缀索引
    • text, blob,很长的varchar类型的列被索引时,必须使用前缀索引
    create table t(bValue blob, index(bValue(10)));
    

    多列索引

    create table t(n0 int, n1 int, n2 int, index mIndex(n0, n1, n2));
    
    • 多列索引使用时,左侧的列必须比右侧的列先出现。举例来说,如果有一个三列的索引(col1, col2, col3),则(col1)(col1, col2)以及 (col1, col2, col3)具备索引搜索功能
    • 一旦左侧的列不是精确匹配时,右侧的列就无法使用了

    索引扩展

    Innodb会通过附加主键列自动扩展每个二级索引

    create table t(id int primary key, age int, d date, index dIndex(d)) engine = Innodb;
    --dIndex自动扩展为(d, id)
    
    SET optimizer_switch = 'use_index_extensions=on';
    --索引扩展默认是开启的,上述命令用于关闭索引扩展
    

    优化器使用生成列索引

    mysql支持在生成的列上建立索引:

    create table t(i int, v int as (i + 1) stored , x int as (i + 2), index vIndex(v));
    
    select * from t where i + 1 > 1;
    --则会使用索引vIndex
    
    select * from t where 1 + i > 1;
    --不会使用索引vIndex
    
    select * from t where i + 2 > 1;
    --不会使用索引vIndex
    

    不可见索引

    • 适用于主键以外的索引
    • 默认情况下,索引可见
    • 把索引设为不可见,可以在不删除索引的情况下测试没有索引时的性能
    • 关键字为visible, invisible 可以作用于create table, create index, alter table
    • 索引的可见性不会影响索引的维护
    • 没有显示主键的表,若具有not nullunique的列,则可能具备隐式主键,如此也不能将其设为不可见
    ALTER TABLE t1 ALTER INDEX i_idx INVISIBLE;
    ALTER TABLE t1 ALTER INDEX i_idx VISIBLE;
    --更改索引可见性
    
    SELECT INDEX_NAME, IS_VISIBLE 
        FROM INFORMATION_SCHEMA.STATISTICS 
        WHERE TABLE_SCHEMA = 'db1' AND TABLE_NAME = 't1';
    --获取索引的可见性
    

    降序索引

    • 降序索引,关键字为desc,将导致键值以降序存储
    • Innodb支持降序索引
    CREATE TABLE t (
      c1 INT, c2 INT,
      INDEX idx1 (c1 ASC, c2 ASC),
      INDEX idx2 (c1 ASC, c2 DESC),
      INDEX idx3 (c1 DESC, c2 ASC),
      INDEX idx4 (c1 DESC, c2 DESC)
    );
    
    ORDER BY c1 ASC, c2 ASC    -- optimizer can use idx1
    ORDER BY c1 DESC, c2 DESC  -- optimizer can use idx4
    ORDER BY c1 ASC, c2 DESC   -- optimizer can use idx2
    ORDER BY c1 DESC, c2 ASC   -- optimizer can use idx3
    

    Innodb的聚簇索引

    • 聚簇索引并不是一种单独的索引类型,而是一种数据存储方式
    • Innodb的聚簇索引实际上在同一结构中保存了B-Tree索引和数据行
    • Innodb通过主键来聚集数据,只聚集在同一页面中的记录,包含相邻主键值的页面可能相距甚远
    • 最好避免随机的(不连续且值的分布范围非常大)聚餐索引
    • Innodb应该尽可能的按照主键递增的顺序插入数据
    • 如果没有定义主键,Innodb会选择一个唯一的非空索引代替如果没有这样的索引,Innodb会隐式定义一个主键作为聚簇索引
    • Innodb中,除聚簇索引外的所有索引都称之为二级索引。二级索引保存的不是指向行的物理地址,而是行的主键值,所以二级索引访问需要两次索引查找

    覆盖索引

    • 如果一个索引包含所有需要查询的字段的值,那么就称之为覆盖索引
    • 覆盖索引必须要存储索引列的值,所以只有B-Tree索引支持覆盖索引
    • Innodb的二级索引,都包含了主键值,意味着其能利用额外的主键列进行覆盖查询

    参考资料

    索引与优化

    生成列

    Innodb索引

    相关文章

      网友评论

          本文标题:索引

          本文链接:https://www.haomeiwen.com/subject/lhocnctx.html