哪个 SQL 更快?选择然后更新 VS。使用内部选择更新

Posted

技术标签:

【中文标题】哪个 SQL 更快?选择然后更新 VS。使用内部选择更新【英文标题】:Which SQL is faster? Select and then Update VS. Update with inner select 【发布时间】:2019-12-17 13:24:11 【问题描述】:

我正在使用 Oracle 数据库。请参阅以下 2 个示例(完全相同):

1.

CREATE OR REPLACE TRIGGER LAST_CHANGE_TRIGGER
BEFORE INSERT
    ON TABLE_X_HAVING_ITEM_ID
FOR EACH ROW

DECLARE
    style_id NUMBER(18);

BEGIN      
    -- 1. get style_id
    SELECT
        ITEM.STYLE_ID
    INTO
        style_id
    FROM
        ITEM
    WHERE
        ITEM.ITEM_ID = :NEW.ITEM_ID;

    -- 2. set last_modified
    UPDATE
        STYLE
    SET
        STYLE.LAST_MODIFIED = SYSDATE
    WHERE
        STYLE.STYLE_ID = style_id;
END;
/

2.

CREATE OR REPLACE TRIGGER LAST_CHANGE_TRIGGER
BEFORE INSERT
    ON TABLE_X_HAVING_ITEM_ID
FOR EACH ROW

BEGIN
    UPDATE
        STYLE
    SET
        STYLE.LAST_MODIFIED = SYSDATE
    WHERE
        STYLE.STYLE_ID = (
            SELECT
                ITEM.STYLE_ID
            FROM
                ITEM
            WHERE
                ITEM.ITEM_ID = :NEW.ITEM_ID
        );
END;
/

我听说 2. 一个会更快。我认为 1. 更容易理解(更直接)。 你能解释/证明 2. 更快吗?如果可以的话,是不是只有oracle才有这种情况?

【问题讨论】:

与性能无关,但是:分配item_id := :NEW.ITEM_ID; 完全没用。您可以在 SQL 语句中直接使用:NEW.ITEM_ID 在我的代码中,我有一个分配 item_id 的 IF-ELSE 块。我把它留给了***,但我忘了删除分配:) 只是仔细检查...TABLE_X_HAVING_ITEM_ID 不同于itemstyle,对吧?向第三个表添加一行会导致设置style 表的last_modified 似乎很奇怪——通常你会认为只有在style 表本身发生更改时才会发生这种情况。跨度> 嘿贾斯汀,也许我不应该从 TABLE_X_HAVING_ITEM_ID 中删除真实姓名。它的名字叫ITEMOPTION,所以它确实属于一种风格! 【参考方案1】:

第二个应该更快,因为您不需要两次往返数据库。

它还允许同时更新多行,以防有多个匹配项。

也就是说,我不明白为什么这个触发器是必要的。您可以在查询数据时查找样式。存储冗余数据——尤其是参考表——似乎是个坏主意。

【讨论】:

我认为触发器很好,因为无论何时更改相关表,都必须将 STYLE.LAST_MODIFIED 更新为当前日期。这是产品所有者的请求。这个触发器很好地满足了这个请求,不是吗? 这是 PL/SQL 代码,那么“两次往返数据库”是什么意思?你的意思是上下文切换?你可能是对的,但我猜在实践中它更像是一种洗涤。我认为我更喜欢第二个读取一致性而不是任何性能差异。另外......这两种方法都不允许更新多行吗? @MatthewMcPeak 。 . .每个查询都需要单独编译,结果需要处理后传回PL/SQL代码。 @MatthewMcPeak 它不会更新多行。此处未显示的约束确保了这一点。 @GordonLinoff 感谢您的帮助!我是这样理解的,但我仍然想更深入地研究这一点。我可以在某处查看实现或对其进行调试吗?

以上是关于哪个 SQL 更快?选择然后更新 VS。使用内部选择更新的主要内容,如果未能解决你的问题,请参考以下文章

std::vector<char> VS std::string,哪个更快?

Dapper vs ADO.Net用反射哪个更快?

数据集与Sql查询(选择,过程,函数)哪个更好用?

SQL 多选一个字段值只选一次 和多次从表里查询但查的字段较少 相比哪个性能更好?为啥?

2dsphere vs 2d index:哪个“更好”/更快?

MIN函数在sql内部如何工作?