2013-02-21 32 views
5

Tôi có một bảng rất đơn giản ->Sử dụng IN() khoản dẫn đến filesort

id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY 
by_id INT UNSIGNED NOT NULL 
posted_on INT UNSIGNED NOT NULL 

cơ bảng của tôi là MyISAM.

Tôi có một chỉ số cột nhiều gọi combo1 trên by_id,posted_on,id

tôi chạy truy vấn này ->

EXPLAIN SELECT * FROM books 
     WHERE by_id = '1' AND posted_on = '0' 
     ORDER BY id DESC LIMIT 7; 

Cột Extra nói Using where và cột then chốt nói combo1

Tuy nhiên, khi tôi chạy truy vấn này ->

EXPLAIN SELECT * FROM books 
     WHERE by_id IN(1,7,10) AND posted_on = '0' 
     ORDER BY id DESC LIMIT 7; 

Cột Extra nói Using where; Using filesort và cột khóa cho biết combo1.

Tại sao filesort xảy ra trong trường hợp thứ hai mặc dù QEP cho thấy trình tối ưu hóa đang sử dụng combo1 chỉ mục có 'id' được lập chỉ mục trong đó.

Trả lời

6

Chỉ mục là cây B +. Điều đó có nghĩa rằng theo by_id 1 có tất cả các bản ghi với post_on 0 và by_id 1, và sau đó bạn có tất cả các id cho các bản ghi đó. Theo by_id 7 tuy nhiên bạn có một nhánh cây khác, có chứa các bản ghi với post_on 0 và chúng chứa các bản ghi với các id của chúng.

Khi bạn có điều khoản, bạn đang lấy 3 nhánh khác nhau của cây, bạn phải hợp nhất chúng và sử dụng chúng, vì id có 1,2,4 có thể dưới by_id 1, nhưng 3,5 dưới by_id 10 ; MySQL truy xuất 1,2,4,3,5 và phải sử dụng chúng.

Trong trường hợp đầu tiên chỉ có một chi nhánh và mỗi chi nhánh đã được sắp xếp

+0

Cảm ơn lời giải thích rất lớn @Darhazer – sanchitkhanna26

+0

xin vui lòng cho biết nếu tôi thì nên loại bỏ 'id' từ chỉ số combo1 .. @Darhazer – sanchitkhanna26

+0

Vâng, tôi 'không chắc chắn nếu MySQL có lợi thế là các chi nhánh đã được đặt hàng và áp dụng merge_sort hay không; có lẽ nó phụ thuộc vào phiên bản là tốt. Nếu không có điểm chuẩn thích hợp, tôi sẽ bảo toàn id trong chỉ mục. Mặt khác, nếu bảng là InnoDB, id được bao gồm ở cuối mỗi chỉ số phụ. Điều này được đưa vào tài khoản trong phân loại chỉ trong MySQL 5.6, nếu tôi nhớ chính xác. –

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