MySQL索引

一、索引

MySQL索引
    索引类型
        数据结构
            B+树索引,用于InnoDB & MyISAM
            哈希索引,用于HEAP,NDB,InnoDB AHI
            Fractal Tree索引,用于TokuDB;LSM,用于RocksDB;空间索引,很少用
        物理存储
            聚集索引(clustered index)
            非聚集索引(non-clustered index)
        逻辑角度
            主键索引(PRIMARY KEY)
            辅助索引(SECONDARY KEY)
                唯一索引/非唯一索引
                联合索引/单列索引:联合索引最多16列
                覆盖索引
                前缀索引:前缀索引的过滤性、对覆盖索引的影响
                案例:怎么给字符串的字段加索引
    索引特点
        MyISAM:主键和辅助索引都是B+树的数据结构,只有是否唯一的区别(主键和唯一索引有唯一属性,其他辅助索引没有唯一属性。B+树叶子节点存储的都是指向行记录的row pointer)
        InnoDB:主键和辅助索引都是B+树的数据结构,但叶子节点存储的键值不一样。主键的叶子节点存储整行数据,而辅助索引的叶子节点存储的是主键的键值(index extensions)
        MyISAM只有索引buffer,InnoDB有数据和索引buffer
    InnoDB索引长度
        索引最大长度(字节)
            767:row_format=REDUNDANT或COMPACT
            3072:row_format=DYNAMIC或COMPRESSED,且innodb_large_prefix=1,且innodb_file_format=Barracuda
        最大排序长度(字节):max_sort_length
        排序算法
            select 返回列的字节总长度<=max_length_for_sort_data:全字段排序,所有返回列放入sort_buffer
            select 返回列的字节总长度>max_length_for_sort_data:rowid排序,order by列+主键放入sort_buffer
        案例:order by是怎么工作的
    索引管理
        创建、删除、改名
        建议/强制/忽略索引:use/force/ignore index(idx1,idx2)
        索引使用率:pt-index-usage/sys.schema_index_statistics
        冗余索引:pt-duplicate-key-checker/sys.schema_redundant_indexes
        无用索引:pt-index-usage/sys.schema_unused_indexes
        统计信息
            表统计信息:show table status/information_schema.tables/mysql.innodb_table_stats
            索引统计信息:show index from table/information_schema.statistics/mysql.innodb_index_stats 
            更新
                innodb_stats_persistent=1、innodb_stats_persistent_sample_pages:默认启用,统计信息持久化存储,每次每个索引采集20个page
                innodb_stats_persistent=0、innodb_stats_transient_sample_pages:统计信息不持久化存储,重启失效,每次每个索引采集8个page
                innodb_stats_auto_recalc:默认启用,持久化下修改数据量>10%时,自动更新统计信息;非持久化下修改数据量>1/16时,自动更新统计信息
                innodb_stats_on_metadata:默认禁用,访问metadate时是否更新统计信息
                innodb_stats_method:控制统计信息对索引中NULL值的算法(nulls_equal、nulls_unequal、nulls_ignored)
            动态/非持久化更新统计信息:重启、修改量超过1/16、analyze table、访问元数据、--auto-rehash、表第一次访问
            单表设定统计模式:create/alter table...stats_persistent=1,stats_auto_recalc=1,stats_sample_pages=200;
        ANALYZE TABLE
            更新索引统计信息
            代价估算:n_sample * (n_cols_in_uniq_i + n_cols_in_non_uniq_i + n_cols_in_pk * (1 + n_non_uniq_i)) * n_part
        案例:MySQL为什么有时候会选错索引
    索引使用注意事项
        什么情况下索引会"失效"
            条件字段函数操作
            隐式类型转换
            隐式字符编码转换
        字段定义允许为NULL对索引有什么影响
            索引查找、统计、值比较,会更加复杂
            在B+树里,所有null值放在最左边,增加搜索代价
            索引的每一行要增加一个字节存储
    索引最佳实践
        mysqld进程消耗CPU长时间过高,99.9%是因为没用好索引
        show processlist用户线程状态经常看到Sending data,也基本上是因为索引不当导致
        避坑
            所有主要列都创建单独索引
            长varchar列创建索引
            基数低的列单独创建索引,或者放在联合索引的最左边
        相关参数优化
            sort-buffer-size/join-buffer-size/read-rnd-buffer-size,4~8MB
            optimizer_switch="index_condition_pushdown=on,mrr=on,mrr_cost_based=off,batched_key_access=on,use_index_extensions=on"
            tmp-table-size=max-heap-table-size,100MB
    案例分享
        index key、index filter、table filter
        调优手段/工具
            desc/explain
                type
                    all:全表扫描,最糟糕的情况
                    index:全索引扫描,大部分情况下,一样糟糕
                key_len
                    只计算index key的索引列长度,不包括用于group by/order by的索引列长度
                    等于索引列字节长度;字符串类型需考虑字符集(utf8mb4=4,utf8=3,gbk=2,latin1=1);日期时间型需考虑精度值;\n若允许NULL,再+1;变长类型(VARCHAR),再+2
                extra
                    Using filesort:没有办法利用现有索引进行排序,需要额外排序
                    Using temporary:需要用临时表存储结果集,通常是因为group by的列上没有索引。也有可能是因为同时有group by\n和order by,但group by和order by的列不一样
                    filesort仅用于单表排序,若多表join时有排序,且排序的列不是驱动表的索引列,则走temporary,再基于temptable进行filesort
            profiling
            flush status
            optimizer_trace
        案例:交易平台慢查询20190516
    MySQL8.0索引新特性
        倒序索引(Descending Indexes)
        不可见索引(Invisible Indexes)
        函数索引
        索引跳跃扫描(Index skip scan)
View Code

posted @ 2019-11-05 23:12  Uest  阅读(301)  评论(0编辑  收藏  举报