`
风雪涟漪
  • 浏览: 513783 次
  • 性别: Icon_minigender_1
  • 来自: 大连->北京
博客专栏
952ab666-b589-3ca9-8be6-3772bb8d36d4
搜索引擎基础(Search...
浏览量:9312
Ae468720-c1b2-3218-bad0-65e2f3d5477e
SEO策略
浏览量:18842
社区版块
存档分类
最新评论

Schema的优化和索引 - 高性能的索引策略 - 覆盖索引(Covering Indexes)

阅读更多

索引是高效找到行的一个方法,但是MySQL也能使用索引找到一个列的数据,因此它不必读取整个行。毕竟索引叶子节点存储了它们索引的数据;当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引包含了(或覆盖了)满足查询结果的数据就叫做覆盖索引(covering indexex)

 

覆盖索引是非常强大的工具并且可以大幅度提升性能。考虑下仅仅读取索引的好处:

 

  • 索引的实体往往小于整个行的大小。如果MySQL仅仅读取索引,意味着访问的数据就非常少了。这对于缓存的工作非常有用,这样相应的时间基本都是来自复制数据而已。对于IO限制也非常有用,因为索引要比数据更小并且更容易的写入内存中。(这对于MyISAM尤其有效,它可以对索引进行压缩,这样索引就变得更小了)。
  • 索引是根据索引值的来排序的,因此IO限制范围的访问相对比从随机硬盘位置所需的IO是较少的。对于一些存储引擎,比如MyISAM,你甚至可以用OPTIMIZE这个表来获取全部的排序索引。这样可使简单的范围查询使用完全连续的索引的访问。
  • 大部分存储引擎缓存索引要好于数据。一些存储引擎,比如MyISAM只缓存索引。因为操作系统缓存了MyISAM的数据,访问数据需要一个系统的调用。这样会导致非常严重的性能问题。尤其对于缓存来说,系统的调用是数据访问消耗最大的一部分。
  • 覆盖索引对与InnoDB表有些特殊的效用。因为InnoDB是聚簇索引。InnoDB的次要索引在它们叶子节点保存了行的主键。因此,次要索引的覆盖可以避免在主键上另一个索引的查找。

在这些场景中,从索引中满足一个查询消耗要比查询行要低很多。

覆盖索引也并不适用于任意的索引类型,索引必须存储列的值。Hash, spatial, 和full-text索引不存储值,因此MySQL只能使用B-TREE。并且不同的存储引擎实现覆盖索引都是不同的。并不是所有的存储引擎都支持它们。

当一个查询被索引所覆盖。(an index-covered query)。你使用EXPLAIN就会发现EXTRA列的值为“Using index”。一个例子,sakila.inventory表由一个多列的索引在store_id, film_id的列上。MySQL能使用索引来访问这两列。如下
mysql> EXPLAIN SELECT store_id, film_id FROM sakila.inventory\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: inventory
         type: index
possible_keys: NULL
          key: idx_store_id_film_id
      key_len: 3
          ref: NULL
         rows: 4673
        Extra: Using index

覆盖索引的语句有些诡异的是会关闭优化。MySQL语句优化器在执行语句之前会决定是否有一个索引覆盖它。假使这个索引覆盖了一个WHERE条件,但是并不是整个查询。如果这个条件评估为false,MySQL51以及以前版本都会取出行。

让我们来看看为什么会这样。以及怎样重写这个查询来解决上面所说的问题。
mysql> EXPLAIN SELECT * FROM products WHERE actor='SEAN CARREY'
    -> AND title like '%APOLLO%'\G
*************************** 1. row ***************************
   id: 1
  select_type: SIMPLE
  table: products
  type: ref
  possible_keys: ACTOR,IX_PROD_ACTOR
  key: ACTOR
  key_len: 52
  ref: const
  rows: 10
Extra: Using where

这个索引不能覆盖这个查询有如下两条原因:
  • 没有索引覆盖这个查询,因为我们选择了这个表的所有列,并且没有一个索引覆盖这些列。理论上来说MySQL还能使用一个捷径:WHERE条件中有一列被索引覆盖,因此MySQL会使用索引先找到这个actor并且检查title是否匹配,之后再取整个行。
  • MySQL不能在索引中执行LIKE操作符。这个受限于底层的存储引擎API。在索引的操作,这只能支持简单的比较。MySQL可以LIKE中匹配前缀,因为把它们转为简单的比较了。但是这个例子中前缀的通配符使使用索引查询变为了不可能。最终。MySQL服务器将会获取和匹配这个行的值,而不是索引的值。
我们可以使用加索引(artist, title, prod_id)和重写查询来解决上面的问题。重写的查询如下
mysql> EXPLAIN SELECT *
    -> FROM products
    ->    JOIN (
    ->       SELECT prod_id
    ->       FROM products
    ->       WHERE actor='SEAN CARREY' AND title LIKE '%APOLLO%'
    ->    ) AS t1 ON (t1.prod_id=products.prod_id)\G

*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: <derived2>
               ...omitted...
*************************** 2. row ***************************
           id: 1
  select_type: PRIMARY
        table: products
               ...omitted...
*************************** 3. row ***************************
           id: 2
  select_type: DERIVED
        table: products
         type: ref
possible_keys: ACTOR,ACTOR_2,IX_PROD_ACTOR
          key: ACTOR_2
      key_len: 52
          ref:
         rows: 11
        Extra: Using where; Using index

现在MySQL在第一阶段的查询使用了覆盖索引,当它找到了在子查询匹配的行的时候。它不会在这个执行语句使用索引。但是总比没有强。

这个优化的有效性完全依靠于有多少行被找到。假使products表包含了1百万行。让我们来看看不同数据集下这两个查询的表现。
  1. 第一个,Sean Carrey有30000个产品并且title包含Apollo有2000行。
  2. 第二个,分别是30000和40
  3. 第三个,分别是50和10
测试结果如下
Dataset     Original query                 Optimized query
Example1  5 queries per sec            5 queries per sec
Example2  7 queries per sec            35 queries per sec
Example3  2400 queries per sec      2000 queries per sec

让我们解释下结果
  • 在例子一中,返回的大数据集。并没有看到优化效果。大部分时间花在读取和发送数据上了。
  • 例子二中,在索引过滤后,第二个条件过滤了很少的数据,让我们看看语句的油画效果:是没优化的语句的5倍之多!效率高的原因是第二个语句仅仅需要查找40行而不是30000行。
  • 第三个例子中,知道了子查询是低效的。在索引过滤数据非常小的情况下,子查询的消耗大于了直接从整张表查询所有数据的消耗。

在MySQL5.1以及之前的版本中,这个优化有的时候可以避免读取没有必要的行。MySQL6.0就会避免一些额外的语句。如果升级的话,就不必优化了。

在大多数的存储引擎中,一个索引所覆盖仅仅是访问列是索引的一部分的查询语句。然而,InnoDB可以使优化更进一步。回忆一下,InnoDB的次要索引在叶子节点中保存了主键的值。意味着InnoDB次要索引可由一个额外的列了。InnoDB就可以使用这一特性来覆盖查询语句了。

举个例子,sakila.actor 表使用了InnoDB并且在last_name有个索引。因此这个索引能覆盖语句来获取主键的值actor_id,即使这一列技术上并不是索引的一部分。
mysql> EXPLAIN SELECT actor_id, last_name
    -> FROM sakila.actor WHERE last_name = 'HOPPER'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: actor
         type: ref
possible_keys: idx_actor_last_name
          key: idx_actor_last_name
      key_len: 137
          ref: const
         rows: 2
        Extra: Using where; Using index


2
0
分享到:
评论
1 楼 fancylee 2013-02-16  
  sakila库中没有找到products表,请问这个表的结构是怎么样的呢?

相关推荐

    MySQL 5.7 手册

    - 索引优化:支持覆盖索引(Covering Indexes)和自适应哈希索引(Adaptive Hash Index),提高查询速度。 - 查询优化器改进:查询优化器算法升级,能更准确地预测查询执行计划的成本,选择最佳路径。 3. **安全...

    mysql-8.0版本

    引入了覆盖索引(Covering Indexes)和索引合并(Index Merge),使得查询性能得到显著提升。此外,还有对JSON字段的索引支持。 6. **ACID事务**: MySQL 8.0继续保持其对ACID(原子性、一致性、隔离性、持久性)...

    安川MP7系列工控系统源码解析:关键算法与硬件交互揭秘

    内容概要:本文深入剖析了安川MP7系列工业控制系统的关键源码,重点介绍了运动轨迹规划、通信协议处理以及故障处理机制等方面的技术细节。通过对实际代码片段的解读,揭示了该系统在硬件寄存器直接访问、特殊功能码处理等方面的独特之处。同时,文中还分享了一些基于实践经验得出的重要参数设置及其背后的故事,如特定摩擦补偿系数的选择原因等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对安川产品有一定了解并希望深入了解其内部工作机制的专业人士。 使用场景及目标:帮助读者掌握安川MP7系列控制器的工作原理,提高对类似系统的维护能力和故障排查效率。对于想要进一步研究或二次开发该系统的开发者来说,也能提供宝贵的参考资料。 其他说明:文章不仅限于理论讲解,还包括了许多来自一线的实际案例和经验教训,使读者能够更好地理解和应用所学知识。

    自动化测试与脚本开发_Python3_pynput_键盘鼠标操作录制执行代码生成工具_用于自动化测试_脚本录制_重复操作模拟_宏命令生成_提高工作效率_支持GUI界面_跨平台兼容_.zip

    自动化测试与脚本开发_Python3_pynput_键盘鼠标操作录制执行代码生成工具_用于自动化测试_脚本录制_重复操作模拟_宏命令生成_提高工作效率_支持GUI界面_跨平台兼容_

    嵌入式八股文面试题库资料知识宝典-深入分析Windows和Linux动态库应用异同.zip

    嵌入式八股文面试题库资料知识宝典-深入分析Windows和Linux动态库应用异同.zip

    嵌入式八股文面试题库资料知识宝典-C语言总结.zip

    嵌入式八股文面试题库资料知识宝典-C语言总结.zip

    风储直流微电网母线电压控制策略与双闭环MPPT技术研究

    内容概要:本文详细探讨了风储直流微电网中母线电压控制的关键技术。首先介绍了风储直流微电网的背景和发展现状,强调了母线电压控制的重要性。接着阐述了永磁风机储能并网技术,解释了永磁风机如何通过直接驱动发电机将风能转化为电能,并确保与电网的同步性和稳定性。然后深入讨论了双闭环控制MPPT技术,这是一种通过内外两个闭环控制系统来实现实时调整发电机运行参数的技术,确保风机始终处于最大功率点附近。最后,文章探讨了储能控制母线电压平衡的方法,即通过储能系统的充放电操作来维持母线电压的稳定。结论部分指出,通过这些技术的有机结合,可以实现对风储直流微电网的有效管理和优化控制。 适合人群:从事新能源技术研发的专业人士、电气工程研究人员、风电系统工程师。 使用场景及目标:适用于希望深入了解风储直流微电网母线电压控制策略的研究人员和技术人员,旨在帮助他们掌握最新的控制技术和方法,以提高系统的稳定性和效率。 其他说明:文章还对未来风储直流微电网的发展进行了展望,指出了智能化和自动化的趋势,以及储能技术的进步对系统性能的影响。

    嵌入式八股文面试题库资料知识宝典-C++object-oriented.zip

    嵌入式八股文面试题库资料知识宝典-C++object-oriented.zip

    【操作系统开发】HarmonyOS目录结构详解:构建高效开发环境与跨设备协同应用

    内容概要:文章详细介绍了HarmonyOS的目录结构及其重要性,从整体框架到核心目录的具体功能进行了全面剖析。HarmonyOS凭借其分布式架构和跨设备协同能力迅速崛起,成为全球操作系统领域的重要力量。文章首先概述了HarmonyOS的背景和发展现状,强调了目录结构对开发的重要性。接着,具体介绍了根目录文件、AppScope、entry和oh_modules等核心目录的功能和作用。例如,AppScope作为全局资源配置中心,存放应用级的配置文件和公共资源;entry目录是应用的核心入口,负责源代码和界面开发。此外,文章还对比了HarmonyOS与Android、iOS目录结构的异同,突出了HarmonyOS的独特优势。最后,通过旅游应用和电商应用的实际案例,展示了HarmonyOS目录结构在资源管理和代码组织方面的应用效果。; 适合人群:具备一定编程基础,尤其是对移动操作系统开发感兴趣的开发者,包括初学者和有一定经验的研发人员。; 使用场景及目标:①帮助开发者快速理解HarmonyOS的目录结构,提高开发效率;②为跨设备应用开发提供理论和技术支持;③通过实际案例学习资源管理和代码组织的最佳实践。; 其他说明:HarmonyOS的目录结构设计简洁明了,模块职责划分明确,有助于开发者更好地管理和组织代码和资源。随着万物互联时代的到来,HarmonyOS有望在开发便利性和生态建设方面取得更大进展,吸引更多开发者加入其生态系统。

    飞轮储能充放电控制Simulink仿真模型:基于永磁同步电机的矢量控制与dq轴解耦

    内容概要:本文详细介绍了飞轮储能充放电控制的Simulink仿真模型,重点在于采用永磁同步电机的矢量控制和dq轴解耦控制策略。充电时,外环控制转速,内环控制dq轴电流;放电时,外环控制直流母线电压,内环同样控制dq轴电流。文中还讨论了硬件与软件环境的选择,以及仿真模型的调试与运行情况,最终得出该模型具有良好的跟随性能和波形完美度。 适用人群:从事电力电子系统、储能技术和Simulink仿真的研究人员和技术人员。 使用场景及目标:适用于需要对飞轮储能系统进行深入研究和仿真的场合,旨在提高充放电效率和稳定性,满足不同应用场景的需求。 其他说明:该仿真模型已调试完成,可以直接用于进一步的研究和实际应用,为未来的飞轮储能技术研发提供了有价值的参考。

    嵌入式八股文面试题库资料知识宝典-北京瑞德方科技.zip

    嵌入式八股文面试题库资料知识宝典-北京瑞德方科技.zip

    嵌入式八股文面试题库资料知识宝典-同方万维硬件测试工程师.zip

    嵌入式八股文面试题库资料知识宝典-同方万维硬件测试工程师.zip

    1_15套python PDF格式.zip

    1_15套python PDF格式.zip

    三相三电平整流器仿真:基于电压电流双闭环控制与SPWM调制的性能分析

    内容概要:本文详细介绍了三相三电平整流器的仿真过程及其性能分析。文中首先概述了三相三电平整流器的基本概念及其在电力系统中的重要作用,接着重点探讨了电压电流双闭环控制方式的工作原理和优势,以及SPWM调制技术的具体应用。通过仿真文件展示了整流器在不同条件下的响应情况,验证了这两种技术的有效性和优越性。最后,作者表达了对未来实际应用的期望。 适合人群:从事电力电子研究的技术人员、高校相关专业师生、对电力控制系统感兴趣的工程爱好者。 使用场景及目标:适用于希望深入了解三相三电平整流器工作原理和技术细节的研究人员;目标是在理论基础上掌握电压电流双闭环控制和SPWM调制的实际应用方法。 其他说明:本文提供的仅为仿真文件,未涉及实物实验数据。

    嵌入式八股文面试题库资料知识宝典-恒光科技.zip

    嵌入式八股文面试题库资料知识宝典-恒光科技.zip

    嵌入式八股文面试题库资料知识宝典-北京天华威视科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-北京天华威视科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-微软研究院笔试题目的答案.zip

    嵌入式八股文面试题库资料知识宝典-微软研究院笔试题目的答案.zip

    Arduino UART实验例程【正点原子EPS32S3】

    Arduino UART实验例程,开发板:正点原子EPS32S3,本人主页有详细实验说明可供参考。

    嵌入式八股文面试题库资料知识宝典-朝歌数码.zip

    嵌入式八股文面试题库资料知识宝典-朝歌数码.zip

    嵌入式八股文面试题库资料知识宝典-Cortex系列.zip

    嵌入式八股文面试题库资料知识宝典-Cortex系列.zip

Global site tag (gtag.js) - Google Analytics