mysql索引-最佳实践是什么?

gojuced7  于 2021-06-20  发布在  Mysql
关注(0)|答案(7)|浏览(519)

我在mysql数据库上使用索引已经有一段时间了,但从来没有正确地了解过它们。一般来说,我会在我将要搜索或选择的任何字段上放置一个索引 WHERE 但有时看起来并不是那么黑白分明。
mysql索引的最佳实践是什么?
示例情况/困境:
如果一个表有六列,并且所有列都可以搜索,我应该索引所有列还是不索引?
索引对性能有哪些负面影响?
如果我有一个varchar 2500列,它可以从我的网站的某些部分进行搜索,我应该索引它吗?

t5zmwmid

t5zmwmid1#

一般来说,索引有助于加速数据库搜索,缺点是占用额外的磁盘空间,速度慢 INSERT / UPDATE / DELETE 查询。使用 EXPLAIN 并阅读结果以了解mysql何时使用您的索引。
如果一个表有六列,并且所有列都可以搜索,我应该索引所有列还是不索引?
索引所有六列并不总是最佳做法。
(a) 在搜索特定信息时,是否要使用这些列中的任何一列?
(b) 这些列的选择性是什么(与表中记录的总量相比,存储了多少不同的值)?
mysql使用了一个基于成本的优化器,它在执行查询时试图找到“最便宜”的路径。低选择性的磁场也不是很好的选择。
索引对性能有哪些负面影响?
已经回答:额外的磁盘空间,在插入-更新-删除期间性能降低。
如果我有一个varchar 2500列,它可以从我的网站的某些部分进行搜索,我应该索引它吗?
尝试全文索引。

xmakbtuz

xmakbtuz2#

你绝对应该花些时间阅读索引,有很多关于它的文章,理解正在发生的事情是很重要的。
广义地说,索引对表的行施加排序。
为了简单起见,假设一个表只是一个大的csv文件。无论何时插入一行,它都会在末尾插入。所以表的“自然”顺序就是插入行的顺序。
想象一下,您已经在一个非常初级的电子表格应用程序中加载了csv文件。这个电子表格所做的只是显示数据,并按顺序对行进行编号。
现在假设您需要在第三列中找到所有具有值“m”的行。考虑到你所拥有的,你只有一个选择。扫描表格,检查每行第三列的值。如果您有很多行,这种方法(“表扫描”)可能需要很长时间!
现在想象一下,除了这个表,还有一个索引。此特定索引是第三列中的值索引。索引以某种有意义的顺序(例如,字母顺序)列出第三列中的所有值,并为每个值提供一个显示该值的行号列表。
现在您有了一个很好的策略来查找第三列的值为“m”的所有行。例如,您可以执行二进制搜索!尽管表扫描需要查找n行(其中n是行数),但在最坏的情况下,二进制搜索只需要查找log-n索引项。哇,那当然容易多了!
当然,如果您有这个索引,并且要向表中添加行(最后,因为这就是我们概念表的工作方式),那么您需要每次都更新索引。所以你在写新行的时候要多做一点工作,但是当你在寻找一些东西的时候,你会节省很多时间。
因此,一般来说,索引会在读效率和写效率之间进行权衡。在没有索引的情况下,插入可以非常快——数据库引擎只是向表中添加一行。添加索引时,引擎必须在执行插入时更新每个索引。
另一方面,阅读速度变得更快。
希望这能涵盖你的前两个问题(正如其他人所回答的——你需要找到正确的平衡点)。
你的第三个场景有点复杂。如果您使用like,索引引擎通常会帮助您将读取速度提高到第一个“%”。换句话说,如果选择where列(如“foo%bar%”),数据库将使用索引查找列以“foo”开头的所有行,然后需要扫描中间行集以查找包含“bar”的子集。选择。。。像“%bar%”这样的列不能使用索引。我希望你能明白为什么。
最后,您需要开始考虑多个列的索引。这个概念是相同的,并且行为类似于类似的东西——本质上,如果在(a,b,c)上有一个索引,引擎将继续从左到右使用索引。因此,对a列的搜索可能会使用(a,b,c)索引,就像对(a,b)的搜索一样。但是,如果搜索的位置是b=5和c=1,则引擎需要执行完整的表扫描
希望这有助于阐明一点,但我必须重申,你最好花几个小时来挖掘好文章,深入解释这些事情。阅读特定数据库服务器的文档也是一个好主意。查询规划器实现和使用索引的方式可能有很大的不同。

watbbzwu

watbbzwu3#

我不会在其他答案中重复一些好的建议,但会补充:
复合指数
您可以创建复合索引—一个包含多列的索引。mysql可以从左到右使用这些。如果你有:

Table A
Id
Name
Category
Age
Description

如果您有一个按顺序包含name/category/age的复合索引,这些where子句将使用该索引:

WHERE Name='Eric' and Category='A'

WHERE Name='Eric' and Category='A' and Age > 18

但是

WHERE Category='A' and Age > 18

不会使用该索引,因为所有内容都必须从左到右使用。
解释
使用explain/explain extended来了解mysql可以使用哪些索引,以及它实际选择的索引。mysql每个查询只使用一个键。

EXPLAIN EXTENDED SELECT * from Table WHERE Something='ABC'

慢速查询日志
打开慢速查询日志以查看哪些查询运行缓慢。
宽列
如果有一个宽列,其中大部分区别发生在前几个字符中,则只能使用索引中的前n个字符。示例:我们有一个referencenumber列定义为varchar(255),但是97%的情况下,引用号是10个字符或更少。我把索引改为只看前10个字符,性能提高了不少。

7xzttuei

7xzttuei4#

查看更多关于掌握索引艺术的演示。
更新12/2012:我发布了一个新的演示:如何设计索引,真的。我于2012年10月在圣克拉拉的zendcon和2012年12月在percona live london上发表了这篇文章。
设计最佳索引的过程必须与应用程序中运行的查询相匹配。
很难推荐关于哪些列最好索引,或者是否应该索引所有列、不索引列、哪些索引应该跨多个列等的通用规则。这取决于您需要运行的查询。
是的,有一些开销,所以不应该不必要地创建索引。但是您应该创建索引,以便快速运行所需的查询。索引的开销通常远远大于它的好处。
对于varchar(2500)列,可能需要使用全文索引或前缀索引:

CREATE INDEX i ON SomeTable(longVarchar(100));

请注意,如果您正在搜索可能位于长varchar中间的单词,那么传统索引就无能为力。为此,请使用全文索引。

j1dl9f46

j1dl9f465#

高效地加载数据:索引加快了检索速度,但减慢了插入和删除以及索引列中值的更新。也就是说,索引减慢了大多数涉及写入的操作。这是因为写入一行不仅需要写入数据行,还需要更改任何索引。一个表的索引越多,需要做的更改就越多,平均性能下降也就越大。大多数表接收的读操作多,写操作少,但是对于写操作百分比高的表,索引更新的成本可能会很高。
避免索引:如果不需要特定的索引来帮助查询更好地执行,则不要创建索引。
磁盘空间:一个索引占用磁盘空间,多个索引相应占用更多空间。这可能会导致您比没有索引时更快地达到表大小限制。尽可能避免索引。
外卖:不要过度索引

czq61nw1

czq61nw16#

1/2)索引会加快某些选择操作,但会减慢其他操作,如插入、更新和删除。这可能是一个很好的平衡。
3) 使用全文索引或者sphinx

luaexgnf

luaexgnf7#

如果一个表有六列,并且所有列都可以搜索,我应该索引所有列还是不索引
您是按字段进行搜索还是使用多个字段进行搜索?搜索最多的字段是哪些?字段类型是什么(索引在int上比在varchars上工作得更好(例如)您是否尝试过对正在运行的查询使用explain?
索引对性能有哪些负面影响
更新和插入会比较慢。此外,还需要额外的存储空间,但这在如今通常并不重要。
如果我有一个varchar 2500列,它可以从我的站点的某些部分进行搜索,我应该索引它吗
不,除非它是唯一的(这意味着它已经被索引了),或者您只搜索该字段上的精确匹配项(不使用like或mysql的全文搜索)。
一般来说,我会在使用where子句搜索或选择的任何字段上放置索引
我通常会索引查询最多的字段,然后是int/booleans/enums,而不是varchars字段。别忘了,通常需要在组合字段上创建索引,而不是在单个字段上创建索引。使用解释,并检查慢日志。

相关问题