MySQL之:索引

索引

  • 索引是特殊数据结构:定义在查找时作为查找条件的字段
  • 索引实现在存储引擎
  • 优点:
    • 索引可以降低服务需要扫描的数据量,减少了I/O次数
    • 索引可以帮助服务器避免排序和使用临时表
    • 索引可以帮助将随机I/O转为顺序I/O
  • 缺点:
    • 占用额外空间,影响插入速度

索引类型:

  • 聚簇(集)索引、非聚簇索引:数据和索引存储顺序是否一致
  • 主键索引、辅组索引
  • 稠密索引、稀疏索引:是否索引了每一个数据项
  • B+ TREE、HASH、R TREE
  • 简单索引、组合索引
    左前缀索引:取前面的字符做索引
    覆盖索引:从索引中即可取出要查询的数据,性能高

B+Tree索引

B+Tree索引:

顺序存储,每一个叶子节点到根节点的距离是相同的;左前缀索引,适合查询范围类的数据

可以使用B-Tree索引的查询类型:
  • 全值匹配:精确所有索引列,如:姓zhang,名sanfeng,年龄30
  • 匹配最左前缀:即只使用索引的第一列,如:姓zhang
  • 匹配列前缀:只匹配一列值开头部分,如:姓以z开头的
  • 匹配范围值:如:姓zhang和姓wang之间
  • 精确匹配某一列并范围匹配另一列:如:姓zhang,名以x开头的只访问索引的查询

B-Tree索引

B-Tree索引的限制:
  • 如果不从最左列开始,则无法使用索引:如:查找名为sanfeng,或姓为g结尾
  • 不能跳过索引中的列:如:查找姓zhang,年龄30的,只能使用索引第一列
  • 如果查询中某个列是为范围查询,那么其右侧的列都无法再使用索引:如:姓zhang,名x%,年龄30,只能利用姓和名上面的索引
特别提示:
  • 索引列的顺序和查询语句的写法应相匹配,才能更好的利用索引
  • 为优化性能,可能需要针对相同的列但顺序不同创建不同的索引来满足不同类型的查询需求

Hash索引

  • hash索引:基于哈希表实现,只有精确匹配索引中的所有列的查询才有效,索引自身只存储索引列对应的哈希值和数据指针,索引结构紧凑,查询性能好
  • 只有Memory存储引擎支持显式hash索引
  • 适用场景:
    只支持等值比较查询,包括=,IN(),<=>
  • 不适合适用hash索引的场景:
    不适用于顺序查询:索引存储顺序的不是值的顺序
    不支持模糊匹配
    不支持范围查询
    不支持部分索引列匹配查找:如A,B列索引,只查询A列索引无效

空间索引(R-Tree):

MyISAM支持空间索引,可以使用任意维度组合查询,使用特有的函数访问,常用于做地理数据存储,使用不多

全文索引(FULLTEXT):

在文本中查找关键词,而不是直接比较索引中的值,类似搜索引擎

冗余和重复索引:

  • 冗余索引:(A),(A,B)
    此为不好的索引使用策略,建议扩展索引,而非冗余
  • 重复索引:已经有索引,再次建立索引

索引优化策略:

  • 独立地使用列:尽量避免其参与运算,独立的列指索引列不能是表达式的一部分,也不能是函数的参数,在where条件中,始终将索引列单独放在比较符合的一侧
  • 左前缀索引:构建指定索引字段的左侧的字符数,要通过索引选择性来评估
    索引选择性:不重复的索引值和数据表的记录总数的比值
  • 多列索引:AND操作时更适合使用多列索引,而非为每个列创建单独的索引
  • 选择合适的索引列顺序:无排序和分组时,将选择性最高放左侧

索引优化建议

  • 只要列中含有NULL值,就最好不要在此列设置索引,符合索引如果有NULL值,此列在使用时也不会使用索引
  • 尽量使用短索引,如果可以,应该制定一个前缀长度
  • 对于经常在where子句使用的列,最好设置索引
  • 对于有多个列where或者order by子句,应该建立复合索引
  • 对于like语句,以%或则 '_' 开头的不会使用索引,以%结尾会使用索引
  • 尽量不要在列上进行运算(函数操作和表达式操作)
  • 尽量不要使用 not in 和 <> 操作
  • 多表连接时,尽量小表驱动大表,即小表 join 大表
  • 在千万级分页时使用 limit
  • 对于经常使用的查询,可以开启缓存
  • 大部分情况连接效率远大于子查询

管理索引

创建索引:

CREATE INDEX index_name ON tbl_name (index_col_name,...);
help CREATE INDEX

删除索引:

DROP INDEX index_name ON tbl_name;

查看索引:

SHOW INDEXES FROM [db_name.]tbl_name;

优化表空间:

OPTIMIZE TABLE tb_name

查看索引的使用:

SET GLOBAL userstat=1;
SHOW INDEX_STATISTICS;


EXPLAIN

  • 通过EXPLAIN来分析索引的有效性
  • EXPLAIN SELECT clause
    获取查询执行计划信息,用来查看查询优化器如何执行查询
  • 输出信息说明:
    参考 https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
  • id:
    当前查询语句中,每个SELECT语句的编号
    复杂类型的查询有三种:
    简单子查询
    用于FROM中的子查询
    联合查询:UNION
    注意:UNION查询的分析结果会出现一个额外匿名临时表
  • select_type:
    简单查询为SIMPLE
    复杂查询:
    SUBQUERY:简单子查询
    PRIMARY:最外面的SELECT
    DERIVED:用于FROM中的子查询
    UNION:UNION语句的第一个之后的SELECT语句
    UNION RESULT:匿名临时表
  • table:SELECT语句关联到的表
  • type:关联类型或访问类型,即MySQL决定的如何去查询表中的行的方式,以下顺序,性能从低到高
    • ALL:全表扫描
    • index:根据索引的次序进行全表扫描;如果在Extra列出现"Using index"表示了使用覆盖索引,而非全表扫描
    • range:有范围限制的根据索引实现范围扫描;扫描位置始于索引中的某一点,结束于另一点
    • ref:根据索引返回表中匹配某单个值的所有行
    • eq_ref:仅返回一个行,但与需要额外与某个参考值做比较
    • const,system:直接返回单个行
  • possible_keys:查询可能会用到的索引
  • key:查询中使用到的索引
  • key_len:在索引使用的字节数
  • ref:在利用key字段所表示的索引完成查询时所用的列或某常量值
  • rows:MySQL估计为找所有的目标行而需要读取的行数
  • Extra:额外信息
    • Using index:MySQL将会使用覆盖索引,以避免访问表
    • Using where:MySQL服务器将在存储引擎检索后,再进行一次过滤
    • Using temporary:MySQL对结果排序时会使用临时表
    • Using filesort:对结果使用一个外部索引排序
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 1、索引组织表 在InnoDB中,表都是根据主键顺序组织存放的,称为索引组织表(index organized t...
    冰河winner阅读 844评论 0 1
  • mysql的索引是存储引擎实现的,而不是服务层实现的,没有统一的标准,不同的引擎支持的索引类型不太一样也不一定支持...
    晓茫阅读 133评论 0 0
  • 索引的分类 索引是在存储引擎中实现的,也就是说不同的存储引擎,会使用不同的索引。MyISAM和InnoDB存储引擎...
    山东大葱哥阅读 1,927评论 5 27
  • 一、mysql数据结构 Mysql的两种主要的存储引擎都依赖的数据结构为B+tree,一种从B-tree改进而来的...
    PeTu阅读 4,749评论 1 16
  • 这几天把索引有关的知识系统看了一遍,现在总结如下。 理解mysql中索引是如何工作可以参考一本书的索引部分,要想在...
    晓晨科科阅读 217评论 0 0