Tôi có một tình huống tham gia cơ sở dữ liệu chung liên quan đến ba bảng. Một bảng, A, là bảng chính có khóa chính có tên là id
. Bảng B và C chứa dữ liệu phụ cho các mục nhập và A, và mỗi cột cũng có một cột có tên là id
là khóa ngoại chỉ đến A. id
. Bây giờ, nếu tôi muốn tất cả dữ liệu từ A, B và C trong một truy vấn, tôi sẽ viết:Bổ sung các điều kiện tham gia vào kết quả Oracle trong một kế hoạch khác
SELECT *
FROM A
INNER JOIN B
ON B.id = A.id
INNER JOIN C
ON C.id = A.id
khóa học nào hoạt động hoàn hảo.
Gần đây, DBA của chúng tôi nói với chúng tôi rằng đây là không hiệu quả trong Oracle, và bạn cần phải tham gia vào điều kiện giữa C và B là tốt, như sau:
SELECT *
FROM A
INNER JOIN B
ON B.id = A.id
INNER JOIN C
ON C.id = A.id AND C.id = B.id
này trông dư thừa đối với tôi, vì vậy tự nhiên tôi đã không không tin ở đây. Cho đến khi tôi thực sự chạy vào một truy vấn chậm mà có một kế hoạch thực hiện khủng khiếp, và quản lý để sửa chữa nó bằng cách thêm chính xác điều kiện tham gia bị thiếu. Tôi chạy giải thích kế hoạch trên cả hai phiên bản: một trong những không có điều kiện truy vấn "dư thừa" có chi phí 1 035 trong khi "cải thiện" một có 389 (và có sự khác biệt rất lớn trong cardinality và byte là tốt). Cả hai truy vấn đều cho ra kết quả tương tự.
Có ai có thể giải thích tại sao điều kiện bổ sung này tạo sự khác biệt không? Với tôi C và B thậm chí không liên quan. Cũng lưu ý rằng nếu bạn lấy đi điều kiện kết nối khác thì nó cũng không kém phần quan trọng - cả hai đều cần phải ở đó.
Tôi đồng ý với bạn Gary: nếu kế hoạch tốt hơn với điều kiện tham gia dự phòng, đó là do số liệu thống kê không chính xác. Nói chung, bạn KHÔNG nên cung cấp thông tin dư thừa. –
Đây là câu trả lời hấp dẫn nhất đối với tôi, bởi vì nó phục hồi một số hy vọng trong Oracle. (Vì vậy, có, tôi là một chút không công bằng thiên vị.) Cho dù đó là lời giải thích thực tế là khó khăn cho bất cứ ai để trả lời. – waxwing