MySql索引设计


title: MySql索引设计

索引设计提纲

索引概述

  • 什么是索引
    索引是存储引擎用于快速找到记录的一种数据结构,这是索引的基本功能。
    索引对于良好的性能非常关键。尤其当数据量越来越大的时候,索引对于性能愈发重要。不恰当的索引会导致随着数据量增大,性能急剧下降。

优点:
1.提高检索速度;
2.帮助服务器避免排序和临时表
3.将随机IO变为顺序IO
缺点:
1.创建和维护索引需要耗费时间,耗费时间的数量随着数据量的增加而增加;
2.索引需要占用物理空间;
3.增加、删除和修改数据时,要动态的维护索引,造成数据的维护速度降低了
综上可以总结出来
1.索引适用于多读少事务的表
2.数据唯一性低的表并不合适
索引并不是最好的工具,总的来说只有查询性能提高大于索引带来的额外开销的时候才有效。
对于特大型的表,可以建立一个元数据信息表,用来查询需要用到的某些特性。

索引类型

索引有很多种类型,不同的存储引擎支持和实现也可能不同。下面我们看下MySql支持的索引类型。

  • B-Tree
    B-Tree通常意味着所有的值按顺序存储,并且叶子页到根的距离相同。下图展示了B-Tree索引的抽象表示。大致反映了InnoDB索引是如何工作的。
    avatar
    B-Tree可以加快访问数据的速度,因为存储引擎不再需要进行全表扫描取而代之的是从索引的跟节点。
    可以使用B-Tree的查询类型
    1.全值匹配
    全值匹配指的是和索引中的所有列进行匹配
    2.匹配最左前缀
    即使用索引的第一列
    3.匹配前缀
    匹配某一列的值的开头某一部分
    4.匹配范围值
    字段范围内容值,或者精确某一列模糊匹配另外一列。
    上面的前提都是从索引最左列开始!如果不明白可以再看看B-Tree树结构图
  • 哈希索引
    哈希索引是基于哈希表实现。只有精确匹配索引所有列的查询才有效。在MySql中只有Memory支持也是默认方式,不过mysql官方文档说是说InnoDB不支持哈希。
    其实InnoDB是可以使用的不过是自适应的,不能人为干预是否在一张表中哈希索引。
  • 空间索引
    MyISAM支持空间索引,不过真没用过不敢多写。
  • 全文索引
    全文索引是一种特殊类型的索引,它查找的是文本中的关键词,而不是直接比较索引中的值。全文索引和其它几类索引的匹配方式完全不一样。

高性能索引策略

  • 独立的列
    我们常看到查询不当的使用索引,或者使得MySql无法使用索引。如果查询中的列不是独立,则MySql就不会使用索引。
    “独立索引”是指索引列不能是表达式的一部分,也不能是函数的参数。
    如下面两句SQL则都是错误例子
    SELECT id FROM test WHERE id+1=5;
    SELECT … WHERE TO_DAYS(CURRENT_DATE)-TO_DAYS(date_col)<=10;
  • 前缀索引
    有时候索引很长的字符列,这会让索引变得大且慢。通常可以索引开始的部分字符,这样可以大大节约索引空间,从而提高索引效率。
    但这样也会降低索引的选择性。索引的选择性是指,不重复的索引值,索引的选择性越高查询效率越高。这里的诀窍就是选择合适的前缀长度以
    保证较高的选择性。为了决定前缀的合适长度,需要找到最常见的值的列表,然后和最常见的列表进行比较。其中还得考虑未来数据的变化性,不能仅仅只是
    靠查几条SQL就随便判断了。SQL如下所示
    ALTER TABLE demo ADD key(city(7));
  • 多列索引
    很多人对多列索引的理解都不够。一个常见的错误就是,为每个列创建独立的索引,或者按照错误的顺序创建多列索引。
    一般由于人们听到一些专家诸如“把WHERE条件里面的列都建立上索引”这些模糊的建议导致。
    avatar
    如上图在EXPLAIN中出现了索引合并策略,实际上出现这种情况多半说明索引建立的很糟糕。
    1.出现服务器对多个索引做相交操作的时候,通常意味着需要一个包含所有列相关的多列索引,而不是多个独立的单列索引。
    2.多个索引做联合操作的时候消耗大量的CPU和内存资源
    3.优化器不会把这些计算到查询成本,优化器只关心读取。使得查询的成本被低估,导致执行计划还不如直接走全表。
  • B-Treee索引选择合适的索引顺序
    正确的顺序依赖于使用该索引的查询,并且同时需要考虑如何更好的满足排序和分组的需求。
  • 聚簇索引
    一般为InnoDB的主键,除此之外不能通过其它方式指定。如果没有主键则找一个非空唯一的列,如果没有这种列则会建立一个不可见的系统默认的主键row_id。
    优点
    1.可以把相关数据保存在一起。
    2.访问速度更快
    3.使用覆盖索引扫描的查询可以使用页节点中的主键值。
    缺点
    1.插入速度严重依赖于插入顺序
    2.更新聚簇索引的代价高,因为会强制每个被更新的行移动到新的位置。并且还会面临页分裂,当插入到某个已满的页中时。
    3.导致全表扫描变慢,当行比较稀疏或者页分裂导致数据存储不连续的情况。
  • 覆盖索引
    MySql可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件。向这样包含满足查询需要的数据的索引称为覆盖索引。
    有时候写SQL的时候可以考虑先通过覆盖索引查出来数据再获取其它数据的方式,稍微提高性能。

欢迎扫码加入知识星球继续讨论
avatar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值