我有一个表,我主要更新,我想知道更新查询是否会受益于where列和更新列的索引或者列在哪里?
答案 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')
如果不存在索引,则只需对表进行一次写入即可 同样,如果索引确实存在,那么每个索引都需要额外写入。
我没有提到主键唯一约束,因为当你需要主键时你真的无法绕过它们,但是在插入之前必须检查每个记录以查看该键是否已存在。这将是一个快速的主键索引寻求,但尽管如此,它是该过程的另一个步骤。步骤越少,速度越快。
现在回到你的身边,基本上,如果你需要更新特定记录,索引将帮助你比扫描整个表更快地找到该记录。找到记录所节省的时间将远远超过更新索引所花费的时间。如果您只是插入而从不读取,那么索引会降低您的速度。它变成了平衡的东西。如果您需要阅读特定记录,那么索引将有很大帮助。但索引越多,写入越慢。