Tôi có truy vấn tự tham gia kép trong đó hiệu suất bị giảm nghiêm trọng khi giá trị tìm kiếm được đổi chỗ.Hiệu suất truy vấn SQL Suy giảm tùy thuộc vào thứ tự của giá trị tìm kiếm
-- 500,000 i/o & 500ms execution
select
fooA.ID
, fooB.ID
from
foo AS fooA
INNER JOIN bar AS barA ON fooA.barID = barA.barID
INNER JOIN foo AS fooB ON fooA.fooID = fooB.fooID -- self join
INNER JOIN bar AS barB ON fooB.barID = barB.barID
where
barA.value = 'xyz'
AND barB.value = '60'
-- 5,000 i/o & 5ms execution
select
fooA.ID
, fooB.ID
from
foo AS fooA
INNER JOIN bar AS barA ON fooA.barID = barA.barID
INNER JOIN foo AS fooB ON fooA.fooID = fooB.fooID -- self join
INNER JOIN bar AS barB ON fooB.barID = barB.barID
where
barA.value = '60'
AND barB.value = 'xyz'
- Giá trị "xyz" được niêm yết 150.000 lần trong "thanh" bảng.
- Giá trị "60" được liệt kê 500 lần trong bảng "thanh".
- Kế hoạch truy vấn giống nhau, ngoại trừ vòng lặp bên trong nhiều nhất trả về 150.000 hàng hoặc 500 hàng tùy thuộc vào giá trị tìm kiếm nào được liệt kê trước tiên.
- Các tìm kiếm thực hiện tìm kiếm trên các chỉ mục không được nhóm.
- Thống kê được cập nhật trên cả hai bảng với FULLSCAN.
Tại sao trình tối ưu hóa truy vấn SQL không xác định chính xác rằng trong cả hai trường hợp, phép nối bên trong nhất của kế hoạch truy vấn phải là số có ít hàng nhất?
Sử dụng các tiêu chí giới hạn số lượng hàng trong truy vấn của bạn nhất luôn là đầu tiên. Một nguyên tắc chung của ngón cái. – JonH
Câu trả lời có thể có: tham số truy vấn, tham số đánh hơi và lập kế hoạch sử dụng lại. –
Bạn có thể tạo các khóa chính của id trên bảng foo và thanh không? –