2012-03-29 9 views
12

Google-fu và so-fu của tôi đang thất bại ở đây, vì vậy tôi cũng có thể hỏi.TSQL - Thứ tự thích hợp để tham gia các bảng là gì?

Tôi có nhiều truy vấn với nhiều lần tham gia trong đó.

Trong một truy vấn, tôi đang tham gia tiêu đề/mục/chi tiết cùng nhau, cũng như tìm kiếm các bit thông tin khác nhau cho các bản ghi này.

Khi tham gia, tôi cố gắng giữ mọi thứ theo thứ tự liên quan của chúng. Ví dụ: Tiêu đề của tôi có hai bảng tra cứu, vì vậy tôi sẽ tham gia vào các tiêu đề trước khi tham gia bảng mục của tôi.

Điều đó có đúng không?

Bạn nên tham gia vào các bảng lớn hơn trước khi tìm kiếm bảng? Hoặc ngược lại?

Tôi có nên sử dụng gợi ý loop khi tham gia vào các bảng nhỏ và một gợi ý merge khi tham gia vào bộ mở không?

Tôi chắc chắn câu trả lời là "nó phụ thuộc", nhưng một số nguyên tắc chung để tham gia hiệu quả và hiệu quả sẽ rất hữu ích. Cảm ơn!

+0

Trong hầu hết các trường hợp, bạn không cần phải chỉ định loại tham gia (hợp nhất/vòng/băm). Nếu bạn làm có thể có vấn đề cơ bản cần được giải quyết thay vì tham gia trợ giúp ban nhạc gợi ý. –

+2

Trừ khi bạn biết rõ mình đang làm gì và bạn hiểu các kế hoạch thực hiện truy vấn, KHÔNG BAO GIỜ sử dụng gợi ý truy vấn. – JotaBe

Trả lời

12

CHỈNH SỬA: Dựa trên nhận xét của bạn (và của Kirk Woll), bạn nên hiểu rằng order of your joins is aesthetic, and does not directly impact the resulting execution plan. Trình tối ưu hóa truy vấn sẽ thực hiện các phép nối theo thứ tự hiệu quả nhất, và sử dụng phép nối tham gia thích hợp phần lớn thời gian mà không cần bất kỳ gợi ý nào.

Khi nói đến tính thẩm mỹ của thứ tự tham gia của bạn, đây là một chút chủ quan, nhưng tôi sẽ nói tham gia các bảng của bạn với nhau theo thứ tự nào hợp lý khi đọc qua truy vấn ... nếu bạn bắt đầu bằng @HeaderId, bắt đầu với bảng đó, và sau đó JOIN vào bảng con:

FROM 
    Header h 
    JOIN Items i ON h.HeaderId = i.HeaderId 
    JOIN Details d ON i.ItemId = d.ItemId 
WHERE 
    h.HeaderId = @HeaderId 

Nhưng, nếu bạn bắt đầu truy vấn của bạn với một @DetailId, tôi sẽ tham gia theo thứ tự ngược lại.

FROM 
    Details d 
    JOIN Items i ON d.ItemId = i.ItemId 
    JOIN Header h ON i.HeaderId = h.HeaderId 
WHERE 
    d.DetailId = @DetailId 

Tuy nhiên, đó là chủ quan và chỉ sở thích cá nhân của tôi.

Nó trở nên ít chủ quan khi bạn bắt đầu bao gồm OUTER JOIN s ... cố gắng cấu trúc truy vấn của bạn để tránh bất kỳ RIGHT OUTER JOIN s và thay vào đó hãy sử dụng LEFT OUTER JOIN.

Không sử dụng các gợi ý tham gia theo mặc định ... thực tế bạn hầu như không bao giờ sử dụng chúng. Trình tối ưu hóa truy vấn thực hiện một công việc rất tốt trong việc chọn kế hoạch thực hiện tối ưu. Tôi chỉ gặp một trường hợp duy nhất mà tôi cần cung cấp gợi ý tham gia để cải thiện kế hoạch ... nó đã giúp mạnh trên máy chủ mà truy vấn đang chạy vào thời điểm đó, nhưng khi cơ sở dữ liệu được di chuyển sang một máy chủ khác, gợi ý tham gia của tôi bị phá hủy hiệu suất của truy vấn. Vì vậy, để nhắc lại, nó thường là một ý tưởng tồi để cung cấp gợi ý tham gia.

+1

Có lẽ OP không biết rằng thứ tự tham gia không liên quan đến kế hoạch thực hiện và hoàn toàn là thẩm mỹ? –

+0

@KirkWoll Đó là một điểm rất tốt mà tôi bỏ qua ... Tôi sẽ làm rõ rằng trong câu trả lời của tôi. –

+0

@Kirk, đó chính xác là lý do tôi hỏi. Thứ tự không liên quan gì cả? – IronicMuffin

0

Trình tự phần lớn là thẩm mỹ, nhưng tôi nghĩ hữu ích khi có một quy ước cho cả thứ tự của các bảng và các điều khoản trong điều kiện ON, để tránh nhầm lẫn.

Các gợi ý truy vấn chỉ dành cho các trường hợp ngoại lệ và trong khi bạn có thể tìm thấy các tình huống cần sử dụng (thường mất hiệu suất để giảm các vấn đề tương tranh), bạn nên luôn tìm cách khắc phục sự cố.

[1] Tôi biết một trường hợp để thực hiện vấn đề:

CREATE TABLE A (
    id int IDENTITY PRIMARY KEY, 
    name varchar 
); 

CREATE TABLE B (
    id int IDENTITY PRIMARY KEY, 
    a_id int FOREIGN KEY REFERENCES A (id), 
    name varchar 
); 

SELECT * 
FROM A 
INNER LOOP JOIN B on A.id = B.a_id; 

SELECT * 
FROM B 
INNER LOOP JOIN A on A.id = B.a_id; 

Các lựa chọn đầu tiên thực hiện hai lần quét chỉ mục, thứ hai làm một quét và tìm kiếm. Đây là một lý do tốt để tránh gợi ý.