Delete SQL将以什么顺序执行?

时间:2015-08-03 06:44:53

标签: sql db2 ibm-midrange db2-400

请参阅我以前的帖子。

Sql Cleanup script, delete from one table that's not in the other 1

使用DB2 for IBM i(As400,Db2)。

我正在执行以下sql作为清理脚本凌晨3点。

DELETE FROM p6prodpf A WHERE (0 = (SELECT COUNT(*) FROM P6OPIPF B WHERE   B.OPIID = A.OPIID))

我有一个不同的进程,在此sql运行的同时插入两条记录,第一条记录是P6OPIPF记录,然后将详细记录插入P6PRODPF

问题所在。 运行SQL清理后,P6PRODPF记录丢失。但请记住,存储记录的过程同时进行。

我如何理解SQL是通过P6PRODPF并检查记录是否在P6OPIPF中,如果它不在P6OPIPF中,则删除P6PRODPF

但是后来我在这个SQL上的I系统导航器中运行了Visual Explain,得到了以下结果。

enter image description here

enter image description here

enter image description here

enter image description here

现在我很困惑。

在Visual解释之后看起来语句以检查P6OPIPF开始。

然后它会显示:如果P6OPIPF中的时间实例中有记录,而P6PRODPF中没有相同键的记录,则删除P6PRODPF

这可以解释我的插入记录和sql脚本的进程同时运行时P6PRODPF被删除的问题。

所以我如何在序列中看到它。(我的理论)

  1. 开始插入两条记录的过程。

  2. 插入两条记录的过程会插入第一条记录     P6OPIPF

  3. 同时运行SQL清理。查询见P6OPIPF     记录并检查它是否有P6PRODPF条记录。在这个阶段     仍然没有插入P6PRODPF,所以Sql认为它需要     删除P6PRODPF
  4. 中的记录
  5. 同时插入两条记录的进程插入     P6PRODPF中的第二条记录。
  6. 因为Sql在那个阶段没有看到P6PRODPF     删除P6PRODPF中新插入的记录,留下P6OPIPF     记录没有P6PRODPF记录。
  7. 我说错了吗?

    我真正想知道的只是上面列出的删除脚本。我如何理解SQL是通过P6PRODPF来检查记录是否在P6OPIPF中,如果它不在P6OPIPF中则删除P6PRODPF。但在视觉解释之后,我可以看到它的开始与检查P6OPIPF。那么删除语句首先检查什么?

    插入代码在CA PLEX生成器中生成。 RPGIV代码。

    我的一个函数将首先插入P6OPIPF(OperationsItem.Update.InsertRow),然后在P6PRODPF(ProductDetail.Update.InsertRow)中插入其详细信息。

    Insert Row function

    将执行删除脚本的我的预定功能代码。

    Scheduled delete script function

    希望它有意义。

3 个答案:

答案 0 :(得分:2)

Visual Explain是了解DB正在做什么的有用工具,特别是在尝试提高性能时。

但SQL不是一种过程语言。当你运行这个语句时,你不应该也不能试着说,数据库正在这样做,然后就是这样做。

虽然对于该特定运行可能是真的,但它高度依赖于可用的数据和资源。您无法围绕所看到的步骤对流程进行编码。

你真的不应该试图同时运行这两个进程,根本没有办法确保你最终会得到什么;至少在使用默认隔离级别时(可能是“no commit”或“read uncommited”,具体取决于接口。)

如果您必须同时运行这两个进程,您可能希望在“可重复读取”或“可序列化”下运行删除;这应该具有锁定被引用的表的效果,以便其他进程不能更改它们。

或者,您可以在读稳定性或更高的隔离级别下运行删除和插入。

答案 1 :(得分:2)

为了解释Visual Explain,DB2将在执行DELETE子句之前检查内部表达式 - 它必须,否则它不知道哪些行受到影响。

归档行未归档的原因是删除脚本在插入脚本之前运行。

答案 2 :(得分:1)

您是否听说过“交易”和“隔离”的概念?通常,针对同一数据库运行的不同进程相互屏蔽(隔离),因此它们在运行时不会看到同时运行的任何其他事务的直接影响。逻辑上,两个事务(一个SQL语句的过程或序列)以串行方式执行。

在您的情况下,第一个过程是“第一个”或“第二个”。如果您重复测试,您可能会看到不同的结果,具体取决于谁是“第一”(逻辑上)。