INSERT 和 UPDATE 操作中如何以及何时使用索引?

Posted

技术标签:

【中文标题】INSERT 和 UPDATE 操作中如何以及何时使用索引?【英文标题】:How and when are indexes used in INSERT and UPDATE operations? 【发布时间】:2016-01-10 13:42:03 【问题描述】:

考虑 this Oracle 文档关于索引,this 关于插入速度和 this *** 上的问题让我得出结论:

索引帮助我们更快地找到信息 主键和唯一键会自动编入索引 插入索引会导致性能下降

但是每次讨论索引时,都只显示SELECT 操作作为示例。

我的问题是INSERTUPDATE 操作中是否使用了索引?何时以及如何?

我的建议是:

UPDATE 可以在WHERE 子句中使用索引(如果子句中的列有索引) INSERT 在使用SELECT 时可以使用索引(但在这种情况下,索引来自另一个表) 或者可能在检查完整性约束时

但我对使用索引没有这么深的了解。

【问题讨论】:

如果表具有外键或其他类型的约束(例如唯一性),则索引与 INSERT 和 UPDATE 操作一起使用。如果您没有外键索引,您甚至会发生臭名昭著的 TM 争用事件。 Oracle 也在依赖表上使用索引,而不仅仅是在您正在使用的表上。互联网和文档中有大量材料,所以我认为没有必要在这里讨论。 小心,您的链接之一(特别是docs.oracle.com/cd/E17952_01/refman-5.1-en/insert-speed.html)是针对 mysql 的,而不是针对 Oracle 的。两个数据库的文档都位于 docs.oracle.com 上,很容易混淆。 感谢您的回答。我知道索引不仅仅用于我正在使用的表。可能我期待着后面有更困难的事情。 :) 这个词是索引而不是索引。 @DwB 见 english.stackexchange.com/questions/61080/… 两者都在英文中有效,尽管在技术领域更倾向于使用 indices 【参考方案1】:

对于 UPDATE 语句,如果优化器认为索引可以加快速度,则可以使用索引。该索引将用于定位要更新的行。索引在某种意义上也是一个表,所以如果索引列正在更新,它显然也需要更新索引。另一方面,如果您在没有 WHERE 子句的情况下运行更新,则优化器可能会选择不使用索引,因为它必须访问整个表,全表扫描可能更有效(但可能仍需要更新索引)。优化器在运行时根据几个参数做出这些决定,例如是否有针对相关表和索引的有效统计信息、受影响的数据量、硬件类型等。

对于 INSERT 语句,虽然 INSERT 本身不需要索引,但索引也需要“插入”,因此需要由 oracle 访问。 INSERT 可能导致使用索引的另一种情况是这样的 INSERT:

INSERT INTO mytable (mycolmn)
SELECT mycolumn + 10 FROM mytable;

【讨论】:

【参考方案2】:

Insert 语句对索引没有直接好处。但是more index on a table cause slower insert operation。考虑一个没有索引的表,如果要在其上添加一行,它将找到具有足够可用空间的表块并存储该行。但是如果该表上有索引,数据库必须确保这些新行也通过索引找到,所以要在有索引的表上添加新行,也需要在索引中输入。这乘以插入操作。 So more index you have, more time you need to insert new rows.

对于update it depends on whether you update indexed column or not。如果您不更新索引列,那么性能应该不会受到影响。 Index can also speed up a update statements if the where conditions can make use of indexes.

【讨论】:

以上是关于INSERT 和 UPDATE 操作中如何以及何时使用索引?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SELECT DELETE INSERT UPDATE 操作获取表的名称

如何手动实现Try Insert和Insert Or Update

如何在没有 MERGE 语句的情况下执行 Update else Insert 操作 win INFORMIX

MySQL数据库INSERTUPDATEDELETE以及REPLACE语句的用法详解

ORACle中对于数据量庞大的表如何用delete+insert来代替update语句操作步骤或者请举例说明

MySQL记录操作