2011-12-21 16 views
6

Tránh sử dụng IN (...) khi chọn trên các trường được lập chỉ mục, Nó sẽ giết hiệu suất của truy vấn SELECT.Tại sao sử dụng IN (...) khi chọn trên các trường được lập chỉ mục, sẽ giết hiệu suất của truy vấn SELECT?

Tôi thấy điều này ở đây: https://wikis.oracle.com/pages/viewpage.action?pageId=27263381

bạn có thể giải thích nó? Tại sao điều đó sẽ giết hiệu suất? Và tôi nên sử dụng cái gì thay vì IN. "OR" tuyên bố có thể?

+0

@BillKarwin paging ...Tuy nhiên, – ajreal

+0

+1 cho liên kết =) – newtover

Trả lời

-1

Tôi tin rằng IN được xử lý giống như một nhóm OR, vì vậy việc sử dụng OR sẽ không giúp ích gì.

Cách khác là tạo bảng tạm thời để giữ các giá trị của mệnh đề IN của bạn và sau đó tham gia với bảng tạm thời đó trong SELECT của bạn.

Ví dụ:

CREATE TEMPORARY TABLE temp_table (v VARCHAR) 

INSERT INTO temp_table VALUES ('foo') 
INSERT INTO temp_table VALUES ('bar') 

SELECT * FROM temp_table tmp, orig_table orig 
WHERE temp_table.v = orig.value 

DROP TEMPORARY TABLE temp_table 
2

Bởi vì MySQL không thể tối ưu hóa nó.

Dưới đây là một ví dụ: (. Xin lỗi vì liên kết bên ngoài Không hiển thị một cách chính xác ở đây)

explain select * from keywordmaster where id in (1, 567899); 

plan

đây là một truy vấn:

explain 
    select * from table where id = 1 
    union 
    select * from keywordmaster where id = 567899 

plan

Như bạn có thể thấy trong truy vấn thứ hai, chúng tôi nhận được refconsttype là const thay vì phạm vi. MySQL không thể tối ưu hóa quét phạm vi.

+0

, truy vấn thứ hai dường như mất nhiều thời gian hơn, ít nhất là trên các tập dữ liệu của tôi. – newtover

+0

@newtover điều này chỉ áp dụng 'khi chọn trên các trường được lập chỉ mục' –

+1

Tôi cũng đã xem xét http://www.amazon.com/High-Performance-MySQL-Optimization-Replication/dp/0596101716 và trạng thái: "Đầu ra của EXPLAIN có thể đôi khi làm cho khó có thể biết liệu MySQL có thực sự tìm kiếm một loạt các giá trị hay không, hoặc cho một danh sách các giá trị ... Chúng tôi không chỉ là cầu kỳ: hai loại truy cập chỉ mục này hoạt động khác nhau. bất kỳ cột nào khác trong chỉ mục, nhưng điều kiện bình đẳng nhiều không có giới hạn đó. " – newtover

3

Để nói sự thật, tuyên bố đó mâu thuẫn với nhiều gợi ý mà tôi đã đọc trong sách và bài viết về MySQL.

Dưới đây là một ví dụ: http://www.mysqlperformanceblog.com/2010/01/09/getting-around-optimizer-limitations-with-an-in-list/

Hơn nữa, expr IN(value, ...) chính nó có cải tiến thêm để đối phó với danh sách giá trị lớn, vì nó là vụ phải được sử dụng như là một thay thế hữu ích cho một số range truy vấn:

Nếu tất cả các giá trị là hằng số, chúng được đánh giá theo loại expr và được sắp xếp. Việc tìm kiếm mục sau đó được thực hiện bằng cách sử dụng tìm kiếm nhị phân. Điều này có nghĩa là IN rất nhanh nếu danh sách giá trị IN bao gồm các hằng số.

INs quá lạm dụng có thể dẫn đến truy vấn chậm. Một số trường hợp được ghi chú trong the article.

0

Prior to MySQL 5.0 có vẻ như mySQL sẽ chỉ sử dụng một chỉ mục duy nhất cho một bảng. Vì vậy, nếu bạn có một số SELECT * FROM tbl WHERE (a = 6 OR b = 33), nó có thể chọn sử dụng chỉ mục hoặc chỉ mục b, chứ không phải cả hai. Lưu ý rằng nó nói các trường, số nhiều. Tôi nghi ngờ lời khuyên đến từ thời điểm đó và công việc xung quanh là kết hợp các kết quả OR, như vậy:

SELECT * FROM tbl WHERE (a = 6) 
UNION 
SELECT * FROM tbl WHERE (b = 33) 
Các vấn đề liên quan