2015-12-05 11 views
6

Chúng tôi có truy vấn tìm kiếm các bản sao trong một trong các bảng của chúng tôi, dựa trên số nhận dạng hiếm khi có sẵn, hãy gọi số rareIdentifier INT(10) UNSIGNED NULL . Chúng tôi có một chỉ mục cũ thông thường trên cột này.MariaDB không sử dụng chỉ mục trên 1 cột tự tham gia do chọn lọc thấp (tất cả các NULL)

Các truy vấn trong câu hỏi như sau:

SELECT a.id, b.id FROM 
    widget a INNER JOIN widget b 
ON a.rareIdentifier = b.rareIdentifier; 

Vấn đề là cho một hoạt động trùng lặp tìm hiểu gần đây, chúng tôi thực sự có 0 hàng với giá trị cho rareIdentifier; tức là tất cả các hàng có NULL cho cột này. MariaDB đã quyết định không sử dụng chỉ mục, chọn cách tiếp cận Using join buffer (flat, BNL join) đã quét toàn bộ bảng.

Nhưng NULL s không thể bằng nhau! Vậy tại sao nó lại cố so sánh từng cặp hàng?

Tôi hiểu rằng MySQL/MariaDB sẽ không sử dụng chỉ mục nếu chọn lọc của nó quá thấp. Tôi tin rằng đây là trường hợp ở đây. Trong thực tế, có vẻ như chỉ có 1 giá trị trong chỉ mục có nghĩa là truy vấn là khá nhiều tức thì.

Bảng này là bảng InnoDB.

+0

Chỉ mục hiện tại của bạn trên bảng đó là gì? – Shawn

Trả lời

0

InnoDB có thể không đủ thông minh để nhận ra rằng so sánh với NULL luôn là NULL, do đó bị lỗi. Có lẽ nó chỉ quyết định rằng "tất cả các giá trị đều giống nhau, vì vậy chúng phải bằng nhau" (nhưng trên thực tế tôi thực sự không biết).

Giải pháp thay thế, thêm ... AND a.rareIdentifier IS NOT NULL sẽ cung cấp cho trình tối ưu hóa đủ gợi ý.

0

Điều này có thể nhanh hơn trong hầu hết các trường hợp, đặc biệt nếu có nhiều hàng với cùng một rareIdentifier.

SELECT rareIdentifier, MIN(id), MAX(id), COUNT(*) 
    FROM tbl 
    WHERE rareIdentifier IS NOT NULL 
    GROUP BY rareIdentifier 
    HAVING COUNT(*) > 1; 

Hoặc bạn có thể sử dụng GROUP_CONCAT(id) thay vì min & tối đa. (Tuy nhiên, nếu có nhiều dups, danh sách sẽ bị cắt bớt.)

Giả sử InnoDB và INDEX(rareIdentifier), điều này cần phải quét rất nhiều 'hiệu quả' của chỉ mục.

Về câu hỏi của bạn ...

thực sự đã có 0 hàng ... MariaDB quyết định không sử dụng chỉ số

Tôi từng thấy rất nhiều trong các phiên bản cũ của MySQL. Tôi tự hỏi liệu Oracle có cố định không, nhưng MariaDB đã bỏ lỡ bản sửa lỗi.

Các vấn đề liên quan