Điều gì tốt hơn trong IN ()? Truy vấn phụ hoặc danh sách các giá trị


7

Nếu tìm kiếm hoặc cập nhật các hàng và sử dụng câu lệnh IN () - tốt hơn là chọn các giá trị với truy vấn phụ hoặc xác định giá trị hoặc không có sự khác biệt về hiệu quả giữa điều này? Ví dụ:

SELECT a FROM b WHERE c IN( SELECT c FROM x )

HOẶC LÀ

SELECT a FROM b WHERE c IN(1,2,3,4,5,6,...hundreds values...)

Câu trả lời:


6

Nếu bạn có các giá trị trong một bảng và cột được lập chỉ mục , tôi sẽ hy vọng nó sẽ hiệu quả hơn so với việc sử dụng danh sách các giá trị. Lưu ý rằng có một số cách để làm điều này - đặc biệt là vì loại truy vấn ( WHERE c IN (SELECT c FROM x)) này không được tối ưu hóa hoàn toàn trong một số phiên bản MySQL không quá cũ:

SELECT a FROM b WHERE c IN ( SELECT c FROM x ) ;

Bạn có thể viết lại (nếu x (c)không có NULLgiá trị) là:

SELECT a FROM b WHERE EXISTS ( SELECT 1 FROM x WHERE x.c = b.c ) ;

hoặc (nếu x (c)có các giá trị duy nhất) là:

SELECT b.a FROM b JOIN x ON x.c = b.c ;

Vì vậy, bây giờ bạn có 4 phiên bản để thử nghiệm. Tất nhiên, hành vi thực tế phụ thuộc vào một số yếu tố khác (ngoài truy vấn, lập chỉ mục, phiên bản) như kích thước bảng, phân phối giá trị, cài đặt mysql, bộ nhớ có sẵn, các truy vấn khác đang chạy, giai đoạn mặt trăng, hiệu quả đĩa, v.v.

Trong tất cả, điều tốt nhất để làm là kiểm tra trong môi trường của bạn, tất cả các tùy chọn có sẵn và chọn những gì phù hợp nhất với bạn.


Cảm ơn ý tưởng với EXISTS, trong môi trường của tôi, nó nhanh hơn gấp 5 lần :)
stix

@stix Khi bạn có kinh nghiệm, có thể bạn sẽ thấy tùy chọn EXISTS hoạt động tốt cho các truy vấn nhất định. Tôi thấy nó hoạt động tốt nhất khi tập kết quả không có bảng phụ nhỏ hơn sau đó số lượng mục khớp trong bảng phụ. Trong các trường hợp khác, bạn có thể thấy nó chậm hơn một trong các tùy chọn được cung cấp.
BillThor

@BillThor điểm tốt, cảm ơn thông tin
stix
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.