mysql更新查询是否从索引中受益?

时间:2011-07-21 00:04:12

标签: mysql indexing

我有一个表,我主要更新,我想知道更新查询是否会受益于where列和更新列的索引或者列在哪里?

3 个答案:

答案 0 :(得分:18)

就在where列上。更新列上的索引实际上会降低查询速度,因为索引必须与数据一起更新。 where列的索引将加速更新,并选择,但减慢一些插入。

删除行时,索引也会导致开销。一般情况下,对于您使用WHERE的列而言,它们是一件好事,对于您加入的列,它们基本上是必需的,或ORDER BY

答案 1 :(得分:13)

这里的大多数人都不知道索引在MySQL中是如何工作的。

这取决于您使用的存储引擎。 InnoDB使用与MyISAM完全不同的索引。这是因为MySQL在存储引擎级别而不是MySQL服务器级别上实现了索引。

我担心这里的大多数人都会根据其他数据库给出答案,其中索引与MySQL的工作方式不同

<强> InnoDB的

InnoDB的情况下。这是因为每当在InnoDB中更新行时,索引也必须更新,因为InnoDB's索引必须是顺序的,所以它必须找出索引的哪个页面节点应该插入并插入那里。有时特定页面可能已满,因此必须拆分页面,浪费空间并增加时间。无论您索引哪一列,都会发生这种情况,因为InnoDB使用聚簇索引,其中索引存储整行的数据。

<强>的MyISAM

在MyISAM的情况下,它没有这个问题。 MyISAM实际上只使用了1列索引,即使您可以在多于1列上设置多个唯一身份验证。此外,MyISAM's索引不会按顺序存储,因此更新非常快。同样,插入也很快,因为MyISAM只是将它插入行的末尾。

<强>结论

因此,关于您的问题,您应该考虑您的架构设计,而不是担心查询是否会使用索引。如果您主要在表上进行更新,我建议您不要使用InnoDB,除非您需要行级锁定,高并发和事务。否则MyISAM对于更新任务会更好。如果使用InnoDB索引,则不会对更新产生任何帮助,尤其是在表格非常大的情况下。

答案 2 :(得分:8)

这个不是直截了当的答案。所以这里。

UPDATE table SET ColumnA = 'something' 

如果ColumnA上存在索引,那么您将获得轻微的性能影响,因为每行将有两次写入操作。首先是表中的数据,然后是索引更新的写入。
你甚至可以有几个索引,每个索引都有ColumnA作为索引的一部分,这意味着除了表行之外你还会有几次写入。您可以看到如何让多个索引开始真正减慢您的更新速度 但是如果ColumnA根本没有编入索引,那么它将只为每一行写一次。

UPDATE table SET ColumnA = 'something' WHERE ColumnB = 'something else'

对于此查询,如果ColumnB上存在索引而不存在ColumnA,则查找记录(称为搜索)和单个写入更新将非常快,并且由于索引不关心columnA,因此不需要更新。
但是如果你索引ColumnA而不是ColumnB,你将首先读取表中的每一行(称为扫描,通常是坏事),虽然读取速度比写入速度快但仍然很慢,然后它将写入表,然后另一个写入索引。基本上是最慢的做事方式。

DELETE table WHERE ColumnB = 'somethingelse'

现在,如果您在此表中的任何列上有索引,则从表中删除两次写入并删除索引中的记录。
如果ColumnB未编入索引,则再次扫描表格从表中删除行并更新索引(如果有)。

INSERT INTO table (ColumnA, ColumnB) VALUES ('something','something else')

如果不存在索引,则只需对表进行一次写入即可 同样,如果索引确实存在,那么每个索引都需要额外写入。

我没有提到主键唯一约束,因为当你需要主键时你真的无法绕过它们,但是在插入之前必须检查每个记录以查看该键是否已存在。这将是一个快速的主键索引寻求,但尽管如此,它是该过程的另一个步骤。步骤越少,速度越快。

现在回到你的身边,基本上,如果你需要更新特定记录,索引将帮助你比扫描整个表更快地找到该记录。找到记录所节省的时间将远远超过更新索引所花费的时间。如果您只是插入而从不读取,那么索引会降低您的速度。它变成了平衡的东西。如果您需要阅读特定记录,那么索引将有很大帮助。但索引越多,写入越慢。