索引是提高查询速度的最重要的工具。当然还有其它的一些技术可供使用,但是 一般来说引起最大性能差异的都是索引的正确使用。在 MySQL 邮件列表中,人们 经常询问那些让查询运行得更快的方法。在大多数情况下,我们应该怀疑数据表 上有没有索引,并且通常在添加索引之后立即解决了问题。当然,并不总是这样 简单 就可以解决问题的,因为优化技术本来就并非总是简单的。然而,如果没 有使用索引, 在很多情况下, 你试图使用其它的方法来提高性能都是在浪费时间。 首先使用 索引来获取最大的性能提高,接着再看其它的技术是否有用。 这一部分讲述了索引是什么以及索引是怎么样提高查询性能的。它还讨论 了在某些环境中索引可能降低性能, 并为你明智地选择数据表的索引提供了一些 指导方 针。在下一部分中我们将讨论 MySQL 查询优化器,它试图找到执行查询 的效率最高的方法。了解一些优化器的知识,作为对如何建立索引的补充,对我 们是有好 处的,因为这样你才能更好地利用自己所建立的索引。某些编写查询 的方法实际上让索引不起作用,在一般情况下你应该避免这种情形的发生。 索引的优点 让我们开始了解索引是如何工作的,首先有一个不带索引的数据表。不带 索引的表仅仅是一个无序的数据行集合。例如,图 1 显示的 ad 表就是不带索引 的表,因 此如果需要查找某个特定的公司,就必须检查表中的每个数据行看它 是否与目标值相匹配。这会导致一次完全的数据表扫描,这个过程会很慢,如果 这个表很大,但 是只包含少量的符合条件的记录,那么效率会非常低。 图 1:无索引的 ad 表 图 2 是同样的一张数据表, 但是增加了对 ad 表的 company_num 数据列的索 引。这个索引包含了 ad 表中的每个数据行的条目,但是索引的条目是按照 company_num 值排序的。现在,我们不是逐行查看以搜寻匹配的数据项,而是使 用索引。假设我们查找公司 13 的所有数据行。我们开始扫描索引并找到 了该公 司的三个值。接着我们碰到了公司 14 的索引值,它比我们正在搜寻的值大。索 引值是排过序的,因此当我们读取了包含 14 的索引记录的时候,我们就知道 再 也不会有更多的匹配记录,可以结束查询操作了。因此使用索引获得的功效是: 我们找到了匹配的数据行在哪儿终止,并能够忽略其它的数据行。另一个功效来 自 使用定位算法查找第一条匹配的条目,而不需要从索引头开始执行线性扫描 (例如,二分搜索就比线性扫描要快一些)。通过使用这种方法,我们可以快速 地定位第 一个匹配的值,节省了大量的搜索时间。数据库使用了多种技术来快 速地定位索引值,但是在本文中我们不关心这些技术。重点是它们能够实现,并 且索引是个好东 西。 图 2:索引后的 ad 表 你可能要问,我们为什么不对数据行进行排序从而省掉索引?这样不是也 能实现同样的搜索速度的改善吗?是的,如果表只有一个索引,这样做也可能达 到相同的 效果。但是你可能添加第二个索引,那么就无法一次使用两种不同方 法对数据行进行排序了(例如,你可能希望在顾客名称上建立一个索引,在顾客 ID 号或电话号 码上建立另外一个索引)。