Để tìm tất cả các thay đổi giữa hai cơ sở dữ liệu, tôi không tham gia các bảng trên pk và sử dụng trường date_modified để chọn bản ghi mới nhất. Việc sử dụng EXCEPT
sẽ tăng hiệu suất vì các bảng có cùng một lược đồ. Tôi muốn viết lại nó với số EXCEPT
, nhưng tôi không chắc liệu việc triển khai cho EXCEPT
có thể thực hiện JOIN
trong mọi trường hợp hay không. Hy vọng rằng ai đó có giải thích kỹ thuật hơn về thời điểm sử dụng EXCEPT
.EXCEPT có thực hiện nhanh hơn JOIN khi các cột trong bảng giống nhau
Trả lời
Không có cách nào bất cứ ai có thể cho bạn biết rằng EXCEPT
sẽ luôn luôn hoặc không bao giờ thực hiện tương đương OUTER JOIN
. Trình tối ưu hóa sẽ chọn một kế hoạch thực hiện phù hợp bất kể bạn viết ý định của mình như thế nào.
Điều đó nói rằng, đây là phương châm của tôi:
Sử dụng EXCEPT
khi ít nhất một những điều sau đây là đúng:
- Truy vấn là dễ đọc hơn (điều này sẽ hầu như luôn thật).
- Hiệu suất được cải thiện.
Và CẢ những điều sau đây là đúng:
- Truy vấn tạo ra kết quả giống hệt nhau về mặt ngữ nghĩa, và bạn có thể chứng minh điều này thông qua thử nghiệm hồi quy đầy đủ, bao gồm tất cả các trường hợp cạnh.
- Hiệu suất không bị suy thoái (một lần nữa, trong tất cả các trường hợp cạnh, cũng như thay đổi môi trường như dọn dẹp vùng đệm, cập nhật số liệu thống kê, xóa bộ đệm kế hoạch và khởi động lại dịch vụ).
Điều quan trọng cần lưu ý rằng nó có thể là một thách thức để viết một EXCEPT
truy vấn tương đương như JOIN
trở nên phức tạp hơn và/hoặc bạn đang dựa vào bản sao một phần của các cột nhưng không phải người khác. Viết số NOT EXISTS
tương đương, trong khi ít có thể đọc được hơn EXCEPT
sẽ khó hơn nhiều - và thường dẫn đến kế hoạch tốt hơn (nhưng lưu ý rằng tôi sẽ không bao giờ nói ALWAYS
hoặc NEVER
, ngoại trừ cách tôi vừa làm).
Trong ví dụ sau, LEFT JOIN
nhanh hơn EXCEPT
bởi 70% (PostgreSQL 9.4.3)
Ví dụ:
Có ba bảng. suppliers
, parts
, shipments
. Chúng tôi cần nhận tất cả các bộ phận không được cung cấp bởi bất kỳ nhà cung cấp nào ở Luân Đôn.
Cơ sở dữ liệu (có chỉ số trên tất cả các cột có liên quan):
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
);
ghi đếm:
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)
Query sử dụng 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
Truy vấn sử dụng LEFT JOIN
bằng bảng, được truy vấn con trả về.
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
- 1. Cách thực hiện LEFT JOIN với hơn 2 bảng?
- 2. LEFT JOIN Đáng kể nhanh hơn INNER JOIN
- 3. Truy vấn SQL có SUM trên cột trong bảng JOIN
- 4. Có phải "SELECT COUNT (cột)" nhanh hơn/chậm hơn "SELECT COUNT (*)" không?
- 5. [x, y, z] .join ('') có thực sự nhanh hơn x + y + z cho chuỗi không?
- 6. Thực hiện biểu thức CStr() bên trong câu lệnh JOIN
- 7. chỉ mục có nhiều cột - ok khi thực hiện truy vấn trên chỉ một cột?
- 8. kết hợp hai cấu trúc bảng giống nhau với các dữ liệu khác nhau
- 9. Fastcall có thực sự nhanh hơn không?
- 10. Chọn tất cả các cột sau JOIN trong LINQ
- 11. Quét bảng so với Thêm chỉ mục - nhanh hơn?
- 12. Làm cách nào để tôi có thể thực hiện truy vấn SQL 'NOT IN' nhanh hơn?
- 13. khi nào java nhanh hơn C++ (hoặc khi nào JIT nhanh hơn được biên dịch trước)?
- 14. Trong PostgreSQL, có nhanh hơn bao gồm các cột văn bản trong cùng một bảng, chứ không phải là một bảng riêng biệt?
- 15. CLR của F # và C# giống nhau tại sao F # nhanh hơn C#
- 16. chọn một bảng có các tên cột khác nhau
- 17. SQL Thay thế để thực hiện INNER JOIN trên một bảng đơn
- 18. CSS để tạo cột trong bảng chiếm nhiều chỗ nhất có thể và các cột khác nhỏ hơn
- 19. Trong MySQL, có nhanh hơn để xóa và sau đó chèn hoặc là nó nhanh hơn để cập nhật các hàng hiện có?
- 20. Tại sao cùng một mã thực hiện nhanh hơn trong chuỗi?
- 21. Chèn một số không thay vì NULL trong khi thực hiện LEFT OUTER JOIN trong MYSQL
- 22. Sum của nhân các cột cho các hàng với căn cước giống nhau trong MySQL
- 23. Cách nhanh hơn để thực hiện Danh sách <T> .Contains()
- 24. mongodb php - cách thực hiện "INNER JOIN" giống như truy vấn
- 25. LEFT JOIN AS cột mới?
- 26. Thực hiện nhanh MD5 trong C++
- 27. Tại sao MySQL JOIN nhanh hơn đáng kể so với WHERE IN (subquery)
- 28. Phương pháp tốt để thực hiện các phép tính giống bảng tính bằng ngôn ngữ lập trình là gì?
- 29. Chỉ chọn một số cột từ bảng trên LEFT JOIN
- 30. thủ tục lưu trữ mysql để tìm kiếm từ các bảng giống hệt nhau
Bạn có cần so sánh tất cả các cột không? Hoặc, có một cột id duy nhất có thể được sử dụng để tham gia không? –
Nhớ lại rằng việc triển khai cơ sở dữ liệu của các truy vấn không thực sự ánh xạ từ 1 đến 1 cho các từ khóa SQL. Có thể nhiều hơn các cấu trúc tương đương ngữ nghĩa sẽ dịch sang cùng một kế hoạch truy vấn. – millimoose
@GordonLinoff Tôi cần phải so sánh tất cả các cột để cập nhật bất kỳ thay đổi nào. Và tôi đang sử dụng khóa chính để tham gia. –