zoukankan      html  css  js  c++  java
  • 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);日期时间型需考虑精度值;
    若允许NULL,再+1;变长类型(VARCHAR),再+2
                    extra
                        Using filesort:没有办法利用现有索引进行排序,需要额外排序
                        Using temporary:需要用临时表存储结果集,通常是因为group by的列上没有索引。也有可能是因为同时有group by
    和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

  • 相关阅读:
    Windows7平台下gitblit服务器安装
    使用JDK的zip编写打包工具类
    MongoDB和Java(7):MongoDB用户管理
    MongoDB和Java(6):Spring Data整合MongoDB副本集、分片集群
    MongoDB和Java(5):Spring Data整合MongoDB(注解配置)
    MongoDB和Java(4):Spring Data整合MongoDB(XML配置)
    MongoDB和Java(3):Java操作MongoB
    MongoDB和Java(2):普通用户启动mongod进程
    Spring MVC 执行原理
    选择性配置-ConditionalOnProperty
  • 原文地址:https://www.cnblogs.com/Uest/p/11802431.html
Copyright © 2011-2022 走看看