理解索引最好的办法是结合示例,所以这里准备了一个索引的案例。

  假设要设计一个在线约会网站,用户信息表有很多列,包裹国家,地区,城市,性别,眼睛颜色,等等。完整必须支持上面这些特征的各种组合来搜索用户,还不行一些根据用户的最后在线时间,其他会员对用户的屏风等对用户进行排序并对结果进行限制。如何世界索引满足上面的负载需求呢?

  出人意料的是第一件需要考虑的事情是需要使用索引来排序,还是先检索数据再排序。使用索引排序会严格限制索引和查询的设计。例如,如果希望使用索引做根据其他会员对用户的评分排序,则WHERE 条件中的 age BETWEEN 18 AND 25 就无法使用索引。如果MySQL使用了某个索引进行范围查询,也就无法再使用另一个索引(或者是该索引的后续字段)进行排序了。如果这是很常见的where 条件,那么我们当然就会认为很多查询需要做排序操作。

  支持多种过滤条件

  现在需要看看那些列拥有很多不同的取值,那些列在where子句中出现的最繁琐。在有更多不同值的列上创建索引的选择性更好。一般来说这样都是对的,因为可以让MySQL更有效的过滤掉不需要的行。

  country的选择性通常不高,但是可能很多查询都会用到。sex列的选择性肯定很低,但也会在很多查询中用到。索引考虑到使用的频率还是建议在创建不同组合所以你的时候讲(sex,country) 作为前缀。

  但根据传统的经验,不是说不应该在选择性地的列上创建索引了吗?那么为什么这里需要将恋歌选择性都很低的字段作为索引的前缀列?我们的脑子坏了?

  我们的脑子当然没有坏。这么做有两个理由:低一点,如前面所述几乎所有的查询都会用到sex列。前面曾提到,几乎每一个查询都会用到sex列,设置会吧网站设计成每次都只能按照某一种姓名搜索用户。更重要的一点是,索引中加上这一列也没有花痴,即使查询中没有使用sex列也可以通过下面的诀窍绕过。

  这个诀窍就是:查询不限制性别,那么可以通过在查询条件中增加AND sex in ('f','m')。来让MySQL选择索引。这样写并不会过滤掉如何行,和没有这个条件时返回的结果相同。但是必须添加上这个条件,MySQL才能匹配索引最左前缀。这个诀窍这这类场景中非常有效,但如果有太多不同的值,就会让in() 列表太长,这样就不行了。

  这个案例显示了一个级别原则:考虑表上素有是选项。当时机索引时,不要指望现有的查询考虑需要哪些需哦因,还需要考虑对查询进行优化。如果发现某些查询需要创建新索引,但是这个索引优惠降低另一些查询的效率,那么应该想一想释放能优化原来的查询,那么应该想一想释放能优化原来的查询。应该同时优化查询和索引以找到最贱的平衡,而不是闭门造车去设计完美的索引。

  接下来,需要考虑其他常见where的组合,并需要了解哪些组合在没有合适索引的情况下就会很慢。(sex,country,age)上的索引就是一个很明显的选择,另外恒友可能还需要(sex,country,region,age)和(sex,country,region,city,age)这样的组合索引。

  这样就会要要大量的索引。如果想尽可能重用索引而不是建立大量的索引组合,可以使用前面提到的IN()来巧妙的避免同时需要(sex,country,age)和(sex,country,region,age)的索引。如果没有指定这个字段所说,就需要定义一个全部国家列表,或国家的全部地区列表,来确保前缀索引有同样的约束(组合所有的国家,地区,性别)将是一个非常庞大的条件。

  这些索引将满足大部分最常见的查询,但是如何为一些生怕的所说条件(比如说has_pictures,eye_color,hair_color和education)来设计索引呢。这些列的选择性高,使用也不频繁,可以选择忽略掉他们,让MySQL多扫描一些额外的行即可。另一个可选的地方是在age列的前面上加上这些列,在查询时使用前面提到过的in()技术来处理所说是没有指定这些场景。

  你可能已经注意到了,我们一直讲age列放在索引的最后面。age列有什么特殊的地方吗?为什么要放在索引的最后?我们总是尽可能让MySQL使用更多的索引列,因为在查询中只能使用索引的最左前缀,直到遇到第一个范围条件列。前面提到的列在WHERE 子句中都是等于条件,但是age列则多半是范围查询(例如,18-25岁之间的人)。

  当然也可以使用in来代替范围查询,例如年龄条件改为in(18,19...25),但不是所有的查询都可以转换。这里秒数的原则是,金坑能将需要做范围查询的列放在索引的最后面,以便游虎丘能使用更多的索引列。

  前面提到的可以在索引中加入更多的列,并通过in()的方式覆盖奈尔不在where子句中的列。但这种技巧也不能滥用,否则可能会带来麻烦。因为每额外添加一个in()条件,优化器需要做的组合将会以指数的形势增加,最终可能会极大的降低查询性能。

  考虑下面WHERE 子句:

  WHERE eye_color in('brown','blue','hazel')AND hair_colr in ('black','red','blonde','borwn') AND sex in ('f','m') 优化器会转成3*4*2=24种组合,执行计划需要价差where子句中所有的24种组合。对于MySQL来说,24种组合并不是很夸张,但如果组合数达到上千个则需要特别小心。老板吗的MySQL在in()组合条件过多时就会有很多问题。查询优化可能花很多时间,并消耗大量的内存。新版本的MySQL在组合数超过一定数量后就不再进行执行计划评估了,可能会导致MySQL不能很好的利用索引。

  避免多个范围条件

  假设我们有一个last_online列并希望通过下面的查询显示在过去几周上限过的用户:

  WHERE eye_color in('brown','blue','hazel')

      AND hair_colr in ('black','red','blonde','borwn')

      AND sex in ('f','m')

      AND last_online > DATE_SUB(NOW(),INTERVAL 7 DAY)

      AND age between 18 and 25

  这个查询有一个问题:他有两个范围条件 last_online 和age列,MySQL可以使用last_onlie 列索引或者age列索引,但无法同时使用它们。

  如果条件中只有last_onlie而没有age,那么我们可能考虑在索引的后面加上last_onlie列。这里考虑如果我们无法把age字段转换成一个in()列表,并且人要求对于同时有last_onlie和age这两个维度的范围查询的速度很快,那么该怎么办?答案是,很遗憾,没有一个直接的办法能够解决这个问题。但是我们能够将其中一个范围查询转换成一个简单的等值比较。为了实现这一点,我们需要事先计算好一个active列,这个字段由地市任务来维护。党用户每次登陆时,将对应值设为1,并且将过去连续7天未曾登陆的用户的值置为零。

  这个方法可以让MySQL使用(active,sex,country,age)索引。active并不是完全精确的,但是对于这个查询来说,对精度的要求没有那么高。如果需要精确的数据,可以吧last_online 列放在where子句中,但不加入到索引中。这和之前通过计算urlhash值来实现url的快速查找类似。所以这个查询无法使用任何索引,但因为这个条件的过滤性不高,即使在索引中加入了该列也没有太大的帮助。换个角度说,缺乏合适的索引对该查询影响也不明显。

  到目前位置,我们可以看到:如果用户希望同时看到活跃和不活跃的用户,可以在查询中使用in()列表。我们已经加入了很多这样的列表,但另一个可选的方案只能是位不同组合列创建单独的索引。至少需要建立如下索引(active,sex,country,age),(active,country,age),(sex,country,age) 和(country,age).这些索引对某个具体的查询来说可能都是更优化的,但是考虑到索引的维护和额外的空间占用的代价,这个可选方案就不是一个好的策略了。

  这这个案例中,优化器的特性是影响索引策略的一个很重要的因素。如果未来办吗的MySQL能够实现松松索引扫描,就能在一个索引上使用多个范围条件,那也就不需要为上面考虑这类型使用in()列表了。

  优化排序

  在这个学习案例中,最后要介绍的是排序。使用文件排序对小数据集是很快的,但如果一个查询的结果又上百万行的话会怎样?例如where子句中只有sex列,如何排序?

  对于那些选择性非常低的列,可以增加一些特殊的索引来做排序。例如可以创建(sex,rating)索引用于如下的查询:

  SELECCT <cols> FROM  profiles WHERE sex='M' ORDER BY rating limit 10;

  这个查询同时使用了order by 和limit ,如果没有索引的话,会很慢。

  即使有索引,如果yoghurt界面上需要翻页,并且翻页到比较靠后时,查询也可能非常慢。

  下面这个查询就可以通过ORDER BY 和LIMIT偏移量的组合翻页到很后面的时候。

  SELECCT <cols> FROM  profiles WHERE sex='M' ORDER BY rating limit 100000,10;

  无论如何创建索引,这种查询都是个严重的问题。因为随着偏移量的增加,MySQL需要花费大量的 时间来扫描需要丢弃的数据。反范式化、预先计算和缓存可能是解决这类查询的仅有策略。一个更好的办法是限制用户能够翻页的数量,实际上这对用户的体验不大,因为用户很少真正在乎搜索过的低10000页。

  优化这类索引的另一个比较好的策略是使用延迟关联,通过使用腹杆索引查询返回需要的主键,在根据这些主键关联原表格所需要的行。这可以减少MySQL扫描那些需要丢弃的行数。下面这个查询显示了如何高效的使用(sex,rating)索引进行排序和分页

  SELECT <cols> FROM profiles INNER JOIN (SELECT <primary key cols> FROM profiles WHERE x.sex = 'M' ORDER BY rating 10000,10) AS X using (<primary key cols>);

  

  

转载于:https://www.cnblogs.com/zhengyanqiu/p/4996337.html

Mysql 索引案例学习相关推荐

  1. mysql索引实例_mysql索引之十:Mysql 索引案例学习

    理解索引最好的办法是结合示例,所以这里准备了一个索引的案例. 假设要设计一个在线约会网站,用户信息表有很多列,包裹国家,地区,城市,性别,眼睛颜色,等等.完整必须支持上面这些特征的各种组合来搜索用户, ...

  2. mysql 索引案例与索引策略

    目录 索引案例学习 支持多种过滤条件 避免多个范围条件 优化排序 分页查询优化 分而治之总是不错的 索引高性能策略 策略总结 独立的列 前缀索引和索引选择性 多列索引 选择合适的索引列顺序 聚簇索引 ...

  3. MYSQL索引结构学习笔记

    mysql 的数据.索引.DDL 等数据,都是以文件形式存储的, 所以导致每次查询都是一次I/O操作,当I/O操作过大时,会严重影响效率 MYSQL索引结构: mysql使用的是B+树来存储索引的,为 ...

  4. MySQL索引知识点学习

    什么是索引? MySQL官方对索引的定义为:索引是帮助MySQL高效获取数据的数据结构.通俗的说,索引就相当于一本书的目录,能加快数据库的查询速度. 一般来说索引本身也很大,不可能全部存储在内存中,因 ...

  5. MySQL索引的学习和研究

    为什么80%的码农都做不了架构师?>>>    这里所谈论只针对B-Tree类型索引,也是MySQL用的最多最普通的索引.创建索引的时候是按照字面量的顺序创建的,这个要特别注意.在B ...

  6. MySQL 索引学习笔记

    MySQL 索引学习笔记 索引基本概念 索引优点 B-Tree 索引 基本原理 使用场景 使用限制 哈希索引 基本原理 使用限制 自适应哈希索引 处理哈希冲突 相关面试题 高性能索引策略 独立的列 前 ...

  7. mysql索引linke和等于_MySQL索引的学习

    MySQL索引的学习 关于使用mysql索引的好处,合理的设计并使用mysql索引能够有效地提高查询效率.对于没有索引的表,单表查询可能几十万数据就是平静,在大型网站单日可能会产生几十万甚至几百万的数 ...

  8. MySQL索引的理解学习,面试不问索引原理就是事务原理

    目录 MySQL执行SQL的整体流程 引言, MySQL索引底层学习原因 磁盘介绍(理解磁盘IO) 索引底层数据结构B+树 B+树(聚集索引) B+树(辅助索引) 思考一下为何使用B+树结构, 不是B ...

  9. MySQL第12天:MySQL索引优化分析之性能优化案例实践

    MySQL索引优化分析之性能优化案例实践 执行计划中各select_type含义可以看:MySQL第11天:MySQL索引优化分析之性能分析 https://weibo01.blog.csdn.net ...

最新文章

  1. 《LeetCode力扣练习》第141题 环形链表 Java
  2. 第2章-神经网络的数学基础(笔记)
  3. 真实经历:整整一年了,他是这样从程序员转型做产品经理的
  4. 删除 多个表_合并汇总多个工作簿多个工作表,删除修改新增更新内容只需刷新...
  5. python编程循环语句_循环语句—Python编程从入门到精通(5)
  6. 边框border(HTML、CSS)
  7. 电脑c语言数字时钟代码大全,数字时钟c语言代码.doc
  8. Web 攻防第一阶段 I-03:收集 Web 站点信息
  9. Win Server 2003搭建Sql注入环境
  10. 将android应用中产生arn的原因写到本地
  11. Java+SSM(Spring+SpringMVC+Mybatis)个性化购物商城推荐系统 电子商务推荐系统 基于用户、项目、聚类、混合的协同过滤推荐算法WebShopRSMEx 源代码下载
  12. 灿烂夏日里的翩翩蝴蝶结
  13. vue打印问题(分页打印、批量打印条形码)
  14. 软件开发质量改进措施_改进可能是软件开发人员面临的最大挑战,因此我们该如何做...
  15. Windows下用ndk编译ffmpeg
  16. Pycharm补丁包使用教程
  17. 信息资源物理服务器包括什么,信息资源数据库
  18. layer.aler点击按钮回调方法
  19. 计算机地图制图算法与原理重点,计算机地图制图原理概述.ppt
  20. backhul 和 fronthaul的区别和含义

热门文章

  1. html5中动画总结,HTML5-CSS3总结学习(二)
  2. 机器人水库涵洞检测_管渠清淤机器人、管道浑水探测机器人……想不到吧?哈排水集团竟然是“科研达人”...
  3. 我与我的CSDN博客的第一天
  4. JAVA调试出现不断在ClassLoader类中执行时的问题?
  5. Elasticsearch 分片和副本策略
  6. SPOJ 104 Highways(最小生成树计数)
  7. 如何获得查询的执行计划?(一)
  8. css补充、JavaScript、Dom
  9. 基础一:JS数据类型
  10. 五分钟深入 Hadoop 内核