Jos*_*den 7 sql sql-server performance join except
要查找两个数据库之间的所有更改,我将继续加入pk上的表并使用date_modified字段来选择最新记录.将使用EXCEPT
提高性能,因为表具有相同的模式.我想用a重写它EXCEPT
,但我不确定在每种情况下执行是否EXCEPT
会执行JOIN
.希望有人对何时使用有更多的技术解释EXCEPT
.
Aar*_*and 13
任何人都无法告诉你EXCEPT
永远或永远不会超过同等水平OUTER JOIN
.无论您如何编写意图,优化程序都将选择适当的执行计划.
那就是说,这是我的指导方针:
至少满足下列条件之一EXCEPT
时使用:
而BOTH以下为真:
重要的是要注意,编写等效EXCEPT
查询可能是一个挑战,因为它JOIN
变得更复杂和/或您依赖于部分列中的重复但不依赖于其他列.写一个NOT EXISTS
等价物,虽然可读性稍差,但EXCEPT
应该更容易实现 - 而且往往会导致一个更好的计划(但请注意我永远不会说ALWAYS
或者NEVER
,除了我刚刚做的方式).
在这篇博客文章中,我展示了至少一个案例,其中EXCEPT
既有正确构造LEFT OUTER JOIN
,也有同等NOT EXISTS
变化.
小智 5
在以下示例中,速度LEFT JOIN
快了EXCEPT
70 %
(PostgreSQL 9.4.3)
例子:
一共有三张桌子。suppliers
, parts
, shipments
. 我们需要获得伦敦任何供应商未提供的所有零件。
数据库(在所有涉及的列上都有索引):
CREATE TABLE suppliers (
id bigint primary key,
city character varying NOT NULL
);
CREATE TABLE parts (
id bigint primary key,
name character varying NOT NULL,
);
CREATE TABLE shipments (
id bigint primary key,
supplier_id bigint NOT NULL,
part_id bigint NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
记录数:
db=# SELECT COUNT(*) FROM suppliers;
count
---------
1281280
(1 row)
db=# SELECT COUNT(*) FROM parts;
count
---------
1280000
(1 row)
db=# SELECT COUNT(*) FROM shipments;
count
---------
1760161
(1 row)
Run Code Online (Sandbox Code Playgroud)
查询使用EXCEPT
.
SELECT parts.*
FROM parts
EXCEPT
SELECT parts.*
FROM parts
LEFT JOIN shipments
ON (parts.id = shipments.part_id)
LEFT JOIN suppliers
ON (shipments.supplier_id = suppliers.id)
WHERE suppliers.city = 'London'
;
-- Execution time: 3327.728 ms
Run Code Online (Sandbox Code Playgroud)
LEFT JOIN
使用表进行查询,由子查询返回。
SELECT parts.*
FROM parts
LEFT JOIN (
SELECT parts.id
FROM parts
LEFT JOIN shipments
ON (parts.id = shipments.part_id)
LEFT JOIN suppliers
ON (shipments.supplier_id = suppliers.id)
WHERE suppliers.city = 'London'
) AS subquery_tbl
ON (parts.id = subquery_tbl.id)
WHERE subquery_tbl.id IS NULL
;
-- Execution time: 1136.393 ms
Run Code Online (Sandbox Code Playgroud)