哪个 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
不同于item
和style
,对吧?向第三个表添加一行会导致设置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,哪个更快?
SQL 多选一个字段值只选一次 和多次从表里查询但查的字段较少 相比哪个性能更好?为啥?