【发布时间】:2017-08-22 14:58:39
【问题描述】:
我正在使用下一个查询从A 表中删除行:
delete from
(select A.* from A
inner join B
on A.id = B.id
where B.note = '000000000000')
并且此查询无限执行(超过 20 分钟),而 select 查询在 3.3 秒内返回 9300 行:
select * from
(select A.* from A
inner join B
on A.id = B.id
where B.note = '000000000000')
问题出在哪里?
P.S.:删除操作需要 40 分钟。
P.P.S.:根据"Which is Most Efficient when Deleting Rows: EXISTS, IN, or a VIEW",所描述的示例没有区别。
更新:情况再次重现,同样的症状“SELECT 很快,DELETE 很慢”
DB-admins检查阻塞,发现有两个会话互相阻塞,一个会话是上面描述的sql-delete语句;另一个未知,但我想它可能是相同的删除语句或相关表中的另一个删除语句。
根据数据库锁定,这似乎是真的:What it is, Why it Matters and What to do About it:
Oracle 的实现是维护不同版本的 相关数据块。在一个事务中进行的未提交更改 在产生它们的交易中可见,而其他 会话将看到旧的、未更改的版本。这样,隔离 被维护并且select 语句永远不会阻塞。
【问题讨论】:
-
一方面,删除行比选择它们花费的时间要长得多——尽管通常不会那么长。另一方面,可能删除被另一个事务阻止 - 等待它提交或回滚?
-
删除是否在 40 分钟后完成,还是仍在继续?
-
@TonyAndrews ,40分钟后成功删除行并且查询完成执行
-
嗯,就是这样。我真的不认为这里的问题与 SQL 语法有任何关系。 40 分钟 9300 行大约是 4 行/秒。这非常非常慢,但如果表中充满了 CLOB/BLOB,或者有许多带有 ON DELETE CASCADE 外键的子表或许多索引等,就会发生这种情况。
-
@TonyAndrews ,似乎是真的。 “A”表与另外两个表有关系。一个关系使用带有 VARCHAR 字段(长度为 20 和 10)的两列,另一个关系使用 NUMBER(长度 22)
标签: oracle inner-join sql-delete