我已经在我的MySQL数据库上使用索引有一段时间了,但从来没有正确地学习过它们。一般来说,我把索引放在任何字段,我将搜索或选择使用WHERE子句,但有时它似乎不是那么黑和白。
MySQL索引的最佳实践是什么?
例子的情况/困境:
如果一个表有六列,并且它们都是可搜索的,我应该索引它们全部还是没有? 索引对性能的负面影响是什么? 如果我有一个varchar2500列,可以从我的网站的部分搜索,我应该索引它吗?
我已经在我的MySQL数据库上使用索引有一段时间了,但从来没有正确地学习过它们。一般来说,我把索引放在任何字段,我将搜索或选择使用WHERE子句,但有时它似乎不是那么黑和白。
MySQL索引的最佳实践是什么?
例子的情况/困境:
如果一个表有六列,并且它们都是可搜索的,我应该索引它们全部还是没有? 索引对性能的负面影响是什么? 如果我有一个varchar2500列,可以从我的网站的部分搜索,我应该索引它吗?
当前回答
如果一个表有六列,他们都是可搜索的,我应该索引他们所有或没有
您是逐个字段搜索还是使用多个字段进行搜索? 哪些字段最常被搜索? 字段类型是什么?(例如,索引在int上比在VARCHARs上工作得更好) 您尝试过对正在运行的查询使用EXPLAIN吗?
索引对性能的负面影响是什么
更新和插入将变慢。此外,还需要额外的存储空间,但这在如今通常并不重要。
如果我有一个varchar2500列,可以从我的网站的部分搜索,我应该索引它
不,除非它是唯一的(这意味着它已经被索引),或者你只搜索该字段的精确匹配(不使用LIKE或mySQL的全文搜索)。
通常我把索引放在任何字段,我将搜索或选择使用WHERE子句
我通常会索引查询次数最多的字段,然后是int / boolean / enum,而不是VARCHARS字段。不要忘记,通常需要在组合字段上创建索引,而不是在单个字段上创建索引。使用EXPLAIN,并检查慢日志。
其他回答
看看像“更多掌握索引的艺术”这样的演讲。
2012年12月更新:我已经发布了我的一个新演示:如何设计索引,真的。2012年10月,我在圣克拉拉的ZendCon和12月的伦敦Percona Live上发表了这篇文章。
设计最佳索引的过程必须与你在应用程序中运行的查询相匹配。
很难推荐任何通用规则,比如哪些列最好索引,或者是否应该索引所有列还是不索引列,哪些索引应该跨多个列,等等。这取决于您需要运行的查询。
是的,有一些开销,所以您不应该创建不必要的索引。但是您应该创建索引,以便快速运行所需的查询。索引的开销通常远远超过它的收益。
对于VARCHAR(2500)列,你可能想使用FULLTEXT索引或前缀索引:
CREATE INDEX i ON SomeTable(longVarchar(100));
请注意,如果您正在搜索可能位于长varchar中间的单词,那么传统的索引就无法提供帮助。为此,使用全文索引。
如果一个表有六列,他们都是可搜索的,我应该索引他们所有或没有
您是逐个字段搜索还是使用多个字段进行搜索? 哪些字段最常被搜索? 字段类型是什么?(例如,索引在int上比在VARCHARs上工作得更好) 您尝试过对正在运行的查询使用EXPLAIN吗?
索引对性能的负面影响是什么
更新和插入将变慢。此外,还需要额外的存储空间,但这在如今通常并不重要。
如果我有一个varchar2500列,可以从我的网站的部分搜索,我应该索引它
不,除非它是唯一的(这意味着它已经被索引),或者你只搜索该字段的精确匹配(不使用LIKE或mySQL的全文搜索)。
通常我把索引放在任何字段,我将搜索或选择使用WHERE子句
我通常会索引查询次数最多的字段,然后是int / boolean / enum,而不是VARCHARS字段。不要忘记,通常需要在组合字段上创建索引,而不是在单个字段上创建索引。使用EXPLAIN,并检查慢日志。
我不会在其他答案中重复一些好的建议,但我会补充:
复合指标
您可以创建复合索引—包含多个列的索引。MySQL可以从左到右使用这些。如果你有:
Table A
Id
Name
Category
Age
Description
如果你有一个复合索引,按顺序包含名字/类别/年龄,这些WHERE子句将使用索引:
WHERE Name='Eric' and Category='A'
WHERE Name='Eric' and Category='A' and Age > 18
but
WHERE Category='A' and Age > 18
不会使用这个索引,因为所有东西都是从左到右使用的。
解释
使用Explain / Explain Extended来了解MySQL可以使用哪些索引以及它实际选择了哪个索引。MySQL每次查询只使用一个键。
EXPLAIN EXTENDED SELECT * from Table WHERE Something='ABC'
慢速查询日志
打开慢速查询日志,查看哪些查询运行慢。
宽栏
如果您有一个宽列,其中大多数区别发生在前几个字符,您可以在索引中只使用前N个字符。例如:我们有一个定义为varchar(255)的ReferenceNumber列,但是97%的情况下,引用号是10个字符或更少。我将索引更改为只查看前10个字符,从而大大提高了性能。
1/2)索引会加速某些选择操作,但会减慢其他操作,如插入、更新和删除。这可以是一个很好的平衡。
3)使用全文索引或狮身人面像
一般来说,索引有助于加速数据库搜索,缺点是使用额外的磁盘空间和减慢INSERT / UPDATE / DELETE查询。使用EXPLAIN并读取结果,以找出MySQL何时使用您的索引。
如果一个表有六列,他们都是可搜索的,我应该索引他们所有或没有他们?
索引所有六列并不总是最佳实践。
(a)在搜索特定信息时,你会使用这些列吗?
(b)这些列的选择性是什么(与表上记录的总量相比,存储了多少不同的值)?
MySQL使用基于成本的优化器,它在执行查询时试图找到“最便宜”的路径。选择性低的领域不是好的选择。
索引对性能的负面影响是什么?
已经回答:额外的磁盘空间,在插入-更新-删除期间性能较低。
如果我有一个varchar2500列,可以从我的网站的部分搜索,我应该索引它吗?
试试FULLTEXT索引。