我在我的 MySQL 数据库上使用索引已有一段时间了,但从未正确地了解它们。通常,我会使用 WHERE
子句在我将要搜索或选择的任何字段上放置一个索引,但有时它看起来并不那么黑白分明。
MySQL 索引的最佳实践是什么?
示例情况/困境:
如果一个表有六列并且所有列都是可搜索的,我应该对所有列进行索引还是不对它们进行索引?
索引对性能有哪些负面影响?
如果我有一个 VARCHAR 2500 列,可以从我网站的某些部分进行搜索,我应该为它建立索引吗?
最佳答案
您绝对应该花一些时间阅读有关索引的内容,关于它的文章很多,理解正在发生的事情很重要。
从广义上讲,索引对表的行进行排序。
为简单起见,将表格想象成一个大的 CSV 文件。每当插入一行时,它都会被插入末尾。因此表的“自然”排序就是插入行的顺序。
假设您已将 CSV 文件加载到一个非常基本的电子表格应用程序中。此电子表格所做的只是显示数据,并按顺序对行进行编号。
现在假设您需要在第三列中找到所有具有某个值“M”的行。鉴于您拥有的资源,您只有一个选择。您扫描表格,检查每一行的第三列的值。如果您有很多行,这种方法(“表扫描”)可能需要很长时间!
现在想象一下,除了这张表之外,您还有一个索引。这个特定的索引是第三列中值的索引。该索引以某种有意义的顺序(例如,按字母顺序排列)列出了第三列中的所有值,并为每个值提供了该值出现的行号列表。
现在您有了一个很好的策略来查找第三列的值为“M”的所有行。例如,您可以执行 binary search !表扫描要求您查看 N 行(其中 N 是行数),而二分查找在最坏的情况下只需要您查看 log-n 索引条目。哇,这肯定容易多了!
当然,如果您有这个索引,并且要向表中添加行(最后,因为这就是我们的概念表的工作方式),您需要每次都更新索引。因此,您在编写新行时会做更多的工作,但在搜索内容时会节省大量时间。
因此,一般来说,索引会在读取效率和写入效率之间进行权衡。没有索引,插入可以非常快——数据库引擎只是向表中添加一行。添加索引时,引擎必须在执行插入时更新每个索引。
另一方面,读取变得更快。
希望这涵盖了您的前两个问题(正如其他人所回答的那样——您需要找到正确的平衡点)。
您的第三种情况稍微复杂一些。如果您使用 LIKE,索引引擎通常会帮助您将读取速度提高到第一个“%”。换句话说,如果你正在 SELECTing WHERE column LIKE 'foo%bar%',数据库将使用索引查找列以“foo”开头的所有行,然后需要扫描中间行集以找到子集包含“酒吧”。 SELECT ... WHERE column LIKE '%bar%' 不能使用索引。我希望你能明白为什么。
最后,您需要开始考虑多个列上的索引。这个概念是相同的,并且与 LIKE 的行为类似——本质上,如果您在 (a,b,c) 上有一个索引,引擎将继续尽可能地从左到右使用该索引。因此,对 a 列的搜索可能会使用 (a,b,c) 索引,就像对 (a,b) 的搜索一样。但是,如果您搜索 WHERE b=5 AND c=1),引擎将需要进行全表扫描
希望这有助于阐明一些问题,但我必须重申,您最好花几个小时四处寻找能够深入解释这些事情的好文章。阅读特定数据库服务器的文档也是一个好主意。查询规划器实现和使用索引的方式千差万别。
关于MySQL 索引 - 最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51512298/