Tôi đã chơi xung quanh (không quan tâm) bằng cách truy xuất một cây nút trong danh sách kề đơn giản với truy vấn đệ quy bằng cách sử dụng các biến cục bộ.SELECT với biến truy vấn không sử dụng INDEXes
Giải pháp tôi có cho đến nay rất thú vị nhưng tôi tự hỏi (và đây là câu hỏi duy nhất của tôi) tại sao MySQL từ chối sử dụng bất kỳ INDEX
nào để tối ưu hóa truy vấn này. Không nên MySQL có thể tra cứu (các) đứa trẻ gần nhất bằng cách sử dụng một số INDEX
?
Tôi rất tò mò vì sao MySQL lại không. Ngay cả khi tôi sử dụng FORCE INDEX
kế hoạch thực hiện không thay đổi.
Đây là truy vấn cho đến nay, với 5
là ID của nút cha:
SELECT
@last_id := id AS id,
parent_id,
name,
@depth := IF(parent_id = 5, 1, @depth + 1) AS depth
FROM
tree FORCE INDEX (index_parent_id, PRIMARY, index_both),
(SELECT @last_id := 5, @depth := -1) vars
WHERE id = 5 OR parent_id = @last_id OR parent_id = 5
Lưu ý rằng lý do không thể là tập dữ liệu nhỏ, bởi vì hành vi không thay đổi khi tôi chỉ định FORCE INDEX (id)
hoặc FORCE INDEX (parent_id)
hoặc FORCE INDEX (id, parent_id)
...
Các tài liệu nói:
Bạn cũng có thể sử dụng FORCE INDEX, hoạt động như USE INDEX (index_list) nhưng bổ sung quét bảng được giả định là rất tốn kém. Nói cách khác, quét bảng chỉ được sử dụng nếu không có cách nào để sử dụng một trong các chỉ mục đã cho để tìm các hàng trong bảng.
Phải có điều gì đó khiến truy vấn không thể sử dụng INDEX, nhưng tôi không hiểu nó là gì.
Disclaimer: Tôi biết có những cách khác để lưu trữ và lấy dữ liệu thứ bậc trong SQL. Tôi biết về mô hình bộ lồng nhau. Tôi không tìm kiếm một triển khai thay thế. Tôi không tìm kiếm các bộ lồng nhau.
Tôi cũng biết truy vấn tự nó là hạt và tạo ra kết quả sai.
Tôi chỉ muốn hiểu (chi tiết) tại sao MySQL không sử dụng INDEX
trong trường hợp này.
đôi khi một bảng có quá ít bản ghi, bạn sẽ sử dụng chỉ mục nhiều hơn là chỉ đọc toàn bộ bảng. – Randy
@randy bây giờ có một đối số chính đáng ... – xandercoded
@Randy xem câu hỏi được cập nhật – Kaii