搜索
首页数据库mysql教程MySQL查询优化技术--索引_MySQL

MySQL查询优化技术--索引_MySQL

Jun 01, 2016 pm 02:06 PM
优化使用技术数据查询索引

MySQL优化MySQL查询

  索引是提高查询速度的最重要的工具。当然还有其它的一些技术可供使用,但是一般来说引起最大性能差异的都是索引的正确使用。在MySQL邮件列表中,人们经常询问那些让查询运行得更快的方法。在大多数情况下,我们应该怀疑数据表上有没有索引,并且通常在添加索引之后立即解决了问题。当然,并不总是这样简单就可以解决问题的,因为优化技术本来就并非总是简单的。然而,如果没有使用索引,在很多情况下,你试图使用其它的方法来提高性能都是在浪费时间。首先使用索引来获取最大的性能提高,接着再看其它的技术是否有用。
  
  这一部分讲述了索引是什么以及索引是怎么样提高查询性能的。它还讨论了在某些环境中索引可能降低性能,并为你明智地选择数据表的索引提供了一些指导方针。在下一部分中我们将讨论MySQL查询优化器,它试图找到执行查询的效率最高的方法。了解一些优化器的知识,作为对如何建立索引的补充,对我们是有好处的,因为这样你才能更好地利用自己所建立的索引。某些编写查询的方法实际上让索引不起作用,在一般情况下你应该避免这种情形的发生。
  
  索引的优点
  
  让我们开始了解索引是如何工作的,首先有一个不带索引的数据表。不带索引的表仅仅是一个无序的数据行集合。例如,图1显示的ad表就是不带索引的表,因此如果需要查找某个特定的公司,就必须检查表中的每个数据行看它是否与目标值相匹配。这会导致一次完全的数据表扫描,这个过程会很慢,如果这个表很大,但是只包含少量的符合条件的记录,那么效率会非常低。
  [[The No.1 Picture.]]
  图1:无索引的ad表
  
  图2是同样的一张数据表,但是增加了对ad表的company_num数据列的索引。这个索引包含了ad表中的每个数据行的条目,但是索引的条目是按照company_num值排序的。现在,我们不是逐行查看以搜寻匹配的数据项,而是使用索引。假设我们查找公司13的所有数据行。我们开始扫描索引并找到了该公司的三个值。接着我们碰到了公司14的索引值,它比我们正在搜寻的值大。索引值是排过序的,因此当我们读取了包含14的索引记录的时候,我们就知道再也不会有更多的匹配记录,可以结束查询操作了。因此使用索引获得的功效是:我们找到了匹配的数据行在哪儿终止,并能够忽略其它的数据行。另一个功效来自使用定位算法查找第一条匹配的条目,而不需要从索引头开始执行线性扫描(例如,二分搜索就比线性扫描要快一些)。通过使用这种方法,我们可以快速地定位第一个匹配的值,节省了大量的搜索时间。数据库使用了多种技术来快速地定位索引值,但是在本文中我们不关心这些技术。重点是它们能够实现,并且索引是个好东西。
  [[The No.2 Picture.]]
  图2:索引后的ad表
  
  你可能要问,我们为什么不对数据行进行排序从而省掉索引?这样不是也能实现同样的搜索速度的改善吗?是的,如果表只有一个索引,这样做也可能达到相同的效果。但是你可能添加第二个索引,那么就无法一次使用两种不同方法对数据行进行排序了(例如,你可能希望在顾客名称上建立一个索引,在顾客ID号或电话号码上建立另外一个索引)。把与数据行相分离的条目作为索引解决了这个问题,允许我们创建多个索引。此外,索引中的行一般也比数据行短一些。当你插入或删除新的值的时候,移动较短的索引值比移动较长数据行的排序次序更加容易。
  
  不同的MySQL存储引擎的索引实现的具体细节信息是不同的。例如,对于MyISAM数据表,该表的数据行保存在一个数据文件中,索引值保存在索引文件中。一个数据表上可能有多个索引,但是它们都被存储在同一个索引文件中。索引文件中的每个索引都包含一个排序的键记录(它用于快速地访问数据文件)数组。
  
  与此形成对照的是,BDB和InnoDB存储引擎没有使用这种方法来分离数据行和索引值,尽管它们也把索引作为排序后的值集合进行操作。在默认情况下,BDB引擎使用单个文件存储数据和索引值。InnoDB使用单个数据表空间(tablespace),在表空间中管理所有InnoDB表的数据和索引存储。我们可以把InnoDB配置为每个表都在自己的表空间中创建,但是即使是这样,数据表的数据和索引也存储在同一个表空间文件中。
  
  前面的讨论描述了单个表查询环境下的索引的优点,在这种情况下,通过减少对整个表的扫描,使用索引明显地提高了搜索的速度。当你运行涉及多表联结(jion)查询的时候,索引的价值就更高了。在单表查询中,你需要在每个数据列上检查的值的数量是表中数据行的数量。在多表查询中,这个数量可能大幅度上升,因为这个数量是这些表中数据行的数量所产生的。
  
  假设你拥有三个未索引的表t1、t2和t3,每个表都分别包含数据列i1、i2和i3,并且每个表都包含了1000条数据行,其序号从1到1000。查找某些值匹配的数据行组合的查询可能如下所示:
  
  SELECT t1.i1, t2.i2, t3.i3
  FROM t1, t2, t3
  WHERE t1.i1 = t2.i2 AND t2.i1 = t3.i3;
  
  这个查询的结果应该是1000行,每个数据行包含三个相等的值。如果在没有索引的情况下处理这个查询,那么如果我们不对这些表进行全部地扫描,我们是没有办法知道哪些数据行含有哪些值的。因此你必须尝试所有的组合来查找符合WHERE条件的记录。可能的组合的数量是1000 x 1000 x 1000(10亿!),它是匹配记录的数量的一百万倍。这就浪费了大量的工作。这个例子显示,如果没有使用索引,随着表的记录不断增长,处理这些表的联结所花费的时间增长得更快,导致性能很差。我们可以通过索引这些数据表来显著地提高速度,因为索引让查询采用如下所示的方式来处理:
  
  1.选择表t1中的第一行并查看该数据行的值。
  
  2.使用表t2上的索引,直接定位到与t1的值匹配的数据行。类似地,使用表t3上的索引,直接定位到与表t2的值匹配的数据行。
  
  3.处理表t1的下一行并重复前面的过程。执行这样的操作直到t1中的所有数据行都被检查过。
  
  在这种情况下,我们仍然对表t1执行了完整的扫描,但是我们可以在t2和t3上执行索引查找,从这些表中直接地获取数据行。理论上采用这种方式运行上面的查询会快一百万倍。当然这个例子是为了得出结论来人为建立的。然而,它解决的问题却是现实的,给没有索引的表添加索引通常会获得惊人的性能提高。
  
  MySQL有几种使用索引的方式:
  
  · 如上所述,索引被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度。
  
  · 对于使用了MIN()或MAX()函数的查询,索引数据列中最小或最大值可以很快地找到,不用检查每个数据行。
  
  · MySQL利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作。
  
  · 有时候MySQL会利用索引来读取查询得到的所有信息。假设你选择了MyISAM表中的被索引的数值列,那么就不需要从该数据表中选择其它的数据列。在这种情况下,MySQL从索引文件中读取索引值,它所得到的值与读取数据文件得到的值是相同的。没有必要两次读取相同的值,因此没有必要考虑数据文件。
  
  索引的代价
  
  一般来说,如果MySQL能够找到方法,利用索引来更快地处理查询,它就会这样做。这意味着,对于大多数情况,如果你没有对表进行索引,就会使性能受到损害。这就是我所描绘的索引优点的美景。但是它有缺点吗?有的,它在时间和空间上都有开销。在实践中,索引的优点的价值一般会超过这些缺点,但是你也应该知道到底有一些什么缺点。
  
  首先,索引加快了检索的速度,但是减慢了插入和删除的速度,同时还减慢了更新被索引的数据列中的值的速度。也就是说,索引减慢了大多数涉及写操作的速度。发生这种现象的原因在于写入一条记录的时候不但需要写入数据行,还需要改变所有的索引。数据表带有的索引越多,需要做出的修改就越多,平均性能的降低程度也就越大。在本文的"高效率载入数据"部分中,我们将更细致地了解这些现象并找出处理方法。
  
  其次,索引会花费磁盘空间,多个索引相应地花费更多的磁盘空间。这可能导致更快地到达数据表的大小限制:
  
  · 对于MyISAM表,频繁地索引可能引起索引文件比数据文件更快地达到最大限制。
  
  · 对于BDB表,它把数据和索引值一起存储在同一个文件中,添加索引引起这种表更快地达到最大文件限制。
  
  · 在InnoDB的共享表空间中分配的所有表都竞争使用相同的公共空间池,因此添加索引会更快地耗尽表空间中的存储。但是,与MyISAM和BDB表使用的文件不同,InnoDB共享表空间并不受操作系统的文件大小限制,因为我们可以把它配置成使用多个文件。只要有额外的磁盘空间,你就可以通过添加新组件来扩展表空间。
  
  使用单独表空间的InnoDB表与BDB表受到的约束是一样的,因为它的数据和索引值都存储在单个文件中。
  
  这些要素的实际含义是:如果你不需要使用特殊的索引帮助查询执行得更快,就不要建立索引。
  
  选择索引
  
  假设你已经知道了建立索引的语法,但是语法不会告诉你数据表应该如何索引。这要求我们考虑数据表的使用方式。这一部分指导你如何识别出用于索引的备选数据列,以及如何最好地建立索引:
  
  用于搜索、排序和分组的索引数据列并不仅仅是用于输出显示的。换句话说,用于索引的最好的备选数据列是那些出现在WHERE子句、join子句、ORDER BY或GROUP BY子句中的列。仅仅出现在SELECT关键字后面的输出数据列列表中的数据列不是很好的备选列:
  
  SELECT
  col_a   FROM
  tbl1 LEFT JOIN tbl2
  ON tbl1.col_b = tbl2.col_c   WHERE
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
MySQL:世界上最受欢迎的数据库的简介MySQL:世界上最受欢迎的数据库的简介Apr 12, 2025 am 12:18 AM

MySQL是一种开源的关系型数据库管理系统,主要用于快速、可靠地存储和检索数据。其工作原理包括客户端请求、查询解析、执行查询和返回结果。使用示例包括创建表、插入和查询数据,以及高级功能如JOIN操作。常见错误涉及SQL语法、数据类型和权限问题,优化建议包括使用索引、优化查询和分表分区。

MySQL的重要性:数据存储和管理MySQL的重要性:数据存储和管理Apr 12, 2025 am 12:18 AM

MySQL是一个开源的关系型数据库管理系统,适用于数据存储、管理、查询和安全。1.它支持多种操作系统,广泛应用于Web应用等领域。2.通过客户端-服务器架构和不同存储引擎,MySQL高效处理数据。3.基本用法包括创建数据库和表,插入、查询和更新数据。4.高级用法涉及复杂查询和存储过程。5.常见错误可通过EXPLAIN语句调试。6.性能优化包括合理使用索引和优化查询语句。

为什么要使用mysql?利益和优势为什么要使用mysql?利益和优势Apr 12, 2025 am 12:17 AM

选择MySQL的原因是其性能、可靠性、易用性和社区支持。1.MySQL提供高效的数据存储和检索功能,支持多种数据类型和高级查询操作。2.采用客户端-服务器架构和多种存储引擎,支持事务和查询优化。3.易于使用,支持多种操作系统和编程语言。4.拥有强大的社区支持,提供丰富的资源和解决方案。

描述InnoDB锁定机制(共享锁,独家锁,意向锁,记录锁,间隙锁,下一键锁)。描述InnoDB锁定机制(共享锁,独家锁,意向锁,记录锁,间隙锁,下一键锁)。Apr 12, 2025 am 12:16 AM

InnoDB的锁机制包括共享锁、排他锁、意向锁、记录锁、间隙锁和下一个键锁。1.共享锁允许事务读取数据而不阻止其他事务读取。2.排他锁阻止其他事务读取和修改数据。3.意向锁优化锁效率。4.记录锁锁定索引记录。5.间隙锁锁定索引记录间隙。6.下一个键锁是记录锁和间隙锁的组合,确保数据一致性。

MySQL查询性能差的常见原因是什么?MySQL查询性能差的常见原因是什么?Apr 12, 2025 am 12:11 AM

MySQL查询性能不佳的原因主要包括没有使用索引、查询优化器选择错误的执行计划、表设计不合理、数据量过大和锁竞争。 1.没有索引导致查询缓慢,添加索引后可显着提升性能。 2.使用EXPLAIN命令可以分析查询计划,找出优化器错误。 3.重构表结构和优化JOIN条件可改善表设计问题。 4.数据量大时,采用分区和分表策略。 5.高并发环境下,优化事务和锁策略可减少锁竞争。

您什么时候应该使用复合索引与多个单列索引?您什么时候应该使用复合索引与多个单列索引?Apr 11, 2025 am 12:06 AM

在数据库优化中,应根据查询需求选择索引策略:1.当查询涉及多个列且条件顺序固定时,使用复合索引;2.当查询涉及多个列但条件顺序不固定时,使用多个单列索引。复合索引适用于优化多列查询,单列索引则适合单列查询。

如何识别和优化MySQL中的慢速查询? (慢查询日志,performance_schema)如何识别和优化MySQL中的慢速查询? (慢查询日志,performance_schema)Apr 10, 2025 am 09:36 AM

要优化MySQL慢查询,需使用slowquerylog和performance_schema:1.启用slowquerylog并设置阈值,记录慢查询;2.利用performance_schema分析查询执行细节,找出性能瓶颈并优化。

MySQL和SQL:开发人员的基本技能MySQL和SQL:开发人员的基本技能Apr 10, 2025 am 09:30 AM

MySQL和SQL是开发者必备技能。1.MySQL是开源的关系型数据库管理系统,SQL是用于管理和操作数据库的标准语言。2.MySQL通过高效的数据存储和检索功能支持多种存储引擎,SQL通过简单语句完成复杂数据操作。3.使用示例包括基本查询和高级查询,如按条件过滤和排序。4.常见错误包括语法错误和性能问题,可通过检查SQL语句和使用EXPLAIN命令优化。5.性能优化技巧包括使用索引、避免全表扫描、优化JOIN操作和提升代码可读性。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。