Đây không phải là quá dễ dàng để trả lời câu hỏi này. Bạn nên biết một điều quan trọng:MySQL xử lý IN (<static values list>)
và IN (<subquery>)
dưới dạng các truy vấn khác nhau
. Đầu tiên là bằng so sánh phạm vi (như .. OR = .. OR =
) trong khi thứ hai bằng = ANY ()
- và nó không giống nhau. Vì vậy, nói ngắn gọn:sử dụng IN
với truy vấn con sẽ gây ra truy vấn với ANY()
và MySQL sẽ không sử dụng chỉ mục cho điều đó ngay cả khi truy vấn con là độc lập và trả về danh sách giá trị tĩnh . Đáng buồn nhưng là sự thật. MySQL không thể dự đoán điều đó và vì vậy chỉ mục sẽ không được sử dụng ngay cả khi nó hiển nhiên. Nếu bạn sẽ sử dụng JOIN
(tức là viết lại IN (<subquery>)
của bạn ) - sau đó MySQL sẽ sử dụng chỉ mục cho JOIN
điều kiện, nếu có thể.
Bây giờ, trường hợp thứ hai có thể là về JOIN
và IN
khi sử dụng các phân vùng. Nếu bạn sẽ sử dụng JOIN
- sau đó, thật đáng buồn - nhưng MySQL cũng không thể dự đoán các phân vùng cho JOIN
trong trường hợp phổ biến - và nó sẽ sử dụng toàn bộ tập hợp các phân vùng cho nó. Thay thế JOIN
thành IN (<static list>)
sẽ thay đổi EXPLAIN PARTITION
picture:MySQL sẽ chỉ sử dụng các phân vùng đó, cần thiết để chọn các giá trị từ phạm vi, được chỉ định trong IN
mệnh đề. Tuy nhiên, một lần nữa, điều này sẽ không hoạt động với IN (<subquery>)
.
Như một kết luận - thật đáng buồn, khi chúng ta đang nói về cách MySQL đang xử lý IN
truy vấn con - và trong trường hợp phổ biến, không thể thay thế nó bằng JOIN
một cách an toàn (đó là về trường hợp phân vùng). Vì vậy, giải pháp phổ biến sẽ là: tách truy vấn phụ khỏi truy vấn chính ở cấp ứng dụng . Nếu chúng ta đang nói về truy vấn con độc lập, trả về danh sách giá trị tĩnh, thì đó là gợi ý tốt nhất - thì bạn có thể thay thế danh sách giá trị đó thành IN (<static list>)
và đạt được lợi ích:MySQL sẽ sử dụng chỉ mục cho nó và, nếu chúng ta đang nói về các phân vùng, thì chỉ những phân vùng thực sự cần thiết mới được sử dụng.