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

mysql更新查询是否受益于索引?,mysql,indexing,Mysql,Indexing,我有一个主要更新的表,我想知道在where列和updated列上有一个索引,或者在just where列上有一个索引,更新查询是否会受益?就在where列上。更新列上的索引实际上会减慢查询速度,因为索引必须随数据一起更新。where列上的索引将加快更新和选择,但会减慢某些插入 删除行时,索引也会导致开销。一般来说,它们是一件好事,尽管在很多列中使用的是,而在您进行连接的列中基本上是必需的,或者按顺序进行操作这不是一个直截了当的答案。这就来了 UPDATE table SET ColumnA =

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

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


删除行时,索引也会导致开销。一般来说,它们是一件好事,尽管在很多列中使用的是
,而在您进行连接的列中基本上是必需的,或者
按顺序进行操作

这不是一个直截了当的答案。这就来了

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')
如果不存在索引,只需对表进行一次写入即可完成。
同样,如果索引确实存在,则为每个索引额外写入一次

我没有提到主键唯一性约束,因为当您需要主键时,您确实无法绕过这些约束,但是在插入之前,必须检查每个记录,看看该键是否已经存在某些内容。这将是一个快速的主键索引搜索,但无论如何,这是过程中的另一个步骤。步骤越少,搜索速度越快将。


现在回到您的,基本上,如果您需要更新特定记录,索引将帮助您比扫描整个表更快地找到该记录。查找该记录所节省的时间将远远超过更新索引所损失的时间。如果您只插入而从不读取,则索引将降低您的速度。这将成为一种平衡如果你需要读取特定的记录,那么索引将非常有用。但是索引越多,写入的速度就越慢。

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

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

恐怕这里的大多数人都是基于其他数据库给出答案的,在这些数据库中,索引的工作方式与MySQL不同

InnoDB

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

MyISAM

就MyISAM而言,它没有这个问题。
MyISAM
实际上只使用一列索引,即使您可以在多个列上设置多个唯一性。而且
MyISAM的索引不是按顺序存储的,因此更新非常快。同样,插入也很快,因为
MyISAM
只在末尾插入它排在第一位

结论


因此,对于你的问题,你应该考虑你的模式设计,而不是担心查询是否会使用索引。如果你主要在表上更新,我建议你不要使用<代码> YNDB < /代码>,除非你需要行级锁定、高并发性和事务处理。否则,代码> MyISAM < /代码>会更好。更新任务。如果您使用的是

InnoDB
索引,则不会更新任务,尤其是在表非常大的情况下。

中的
列上的索引(可能会)帮助。可能意味着如果它能帮助等价的
选择
,它会有所帮助。例如,如果您有一个
其中id>3
条件,并且几乎所有id都大于3,则不会使用索引。关于问题的第二部分,请使用
上的索引(wherecolumn,updatecolumn)
可能也有帮助。但我认为这只是因为MySQL检查并没有更新更新更新后的值与列的现有值相同。因此,
update t SET a=7,其中grp=47
可能会形成一个
(grp,a)
索引如果有许多行的
grp=47
a
已经等于
7
。您使用的存储引擎是什么,表的结构是什么,以及更新查询是什么?这些都可能对答案产生影响。更新索引完全由我自己完成