2009-07-17 34 views
7

Tôi có một chỉ mục tổng hợp dựa trên 3 cột, hai trong số đó bị ràng buộc trong truy vấn của tôi và thứ 3 là theo thứ tự theo mệnh đề nào đó mysql không sử dụng chỉ mục để sắp xếp.Tối ưu hóa truy vấn mysql của tôi để sử dụng chỉ mục để phân loại

 
explain select * from videos where public_private='public' and approved='yes' order by number_of_views desc; 

+----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+ 
| id | select_type | table | type | possible_keys     | key | key_len | ref | rows | Extra  | 
+----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+ 
| 1 | SIMPLE  | videos | ALL | approved,approved_3,approved_2 | NULL | NULL | NULL | 1476818 | Using where; Using filesort | 
+----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+ 

Cấu trúc bảng như sau:

CREATE TABLE `videos` (
    `indexer` int(9) NOT NULL auto_increment, 
    `user_id` int(9) default NULL, 
    `public_private` varchar(24) default NULL, 
    `approved` varchar(24) default NULL, 
    `number_of_views` int(9) default NULL, 
    PRIMARY KEY (`indexer`), 
    KEY `approved` (`approved`,`user_id`), 
    KEY `approved_3` (`approved`,`public_private`,`indexer`), 
    KEY `approved_2` (`approved`,`public_private`,`number_of_views`), 
) ENGINE=MyISAM AUTO_INCREMENT=1969091 DEFAULT CHARSET=utf8 | 

Những gì tôi nên làm gì để buộc mysql sử dụng chỉ số để phân loại kết quả?

Trả lời

13

Tôi tin rằng các truy vấn mà bạn có lẽ là phù hợp với một tỷ lệ lớn các dữ liệu trong bảng. Trong các tình huống như vậy, trình tối ưu hóa MySQL thường chọn quét bảng và bỏ qua chỉ mục hoàn toàn, vì nó thực sự nhanh hơn so với việc đọc thêm toàn bộ chỉ mục và sử dụng nó để chọn dữ liệu. Vì vậy, trong trường hợp này, tôi đoán rằng public_private='yes' and approved='yes' khớp với một phần tốt trong bảng của bạn. Do đó, nếu MySQL bỏ qua bằng cách sử dụng chỉ mục vì điều này, thì nó không có sẵn để sắp xếp một trong hai.

Nếu bạn thực sự muốn nó sử dụng một chỉ số, sau đó là giải pháp sẽ được sử dụng FORCE INDEX:

select * from videos FORCE INDEX (approved_2) where public_private='public' and approved='yes' order by number_of_views desc; 

Tuy nhiên, tôi sẽ chạy một số xét nghiệm để đảm bảo rằng những gì bạn đang nhận được là thực sự nhanh hơn những gì trình tối ưu hóa MySQL đã chọn để làm. Rõ ràng là trình tối ưu hóa does have some issues với việc lựa chọn để đặt hàng, vì vậy bạn chắc chắn có thể cung cấp cho nó một shot và xem liệu bạn có được cải thiện hiệu suất hay không.

+0

FORCE INDEX giải quyết được sự cố. Truy vấn thực thi nhanh hơn nhiều và bạn đã đúng về truy vấn khớp với một phần lớn cơ sở dữ liệu. –

+0

Công cụ tốt, vui vì nó hoạt động. – zombat

-2

Thứ tự quan trọng trong các phím tổng hợp. Tôi quên các quy tắc, nhưng hãy thử theo thứ tự khác.

-2

thêm chỉ mục riêng biệt vào cột number_of_views và xem liệu nó có hoạt động hay không.

Nếu một phím là sự kết hợp của 3 cột, nó sẽ sử dụng chìa khóa đặc biệt chỉ khi nó được sử dụng tất cả 3 để thực hiện một hoạt động

+0

Không chính xác là: Nếu khóa là sự kết hợp của 3 cột, nó sẽ sử dụng khóa đó khi đang sử dụng cột đầu tiên hoặc kết hợp hai cột đầu tiên hoặc cả ba cột –

1

Thứ tự không quan trọng trong các phím tổng hợp. Nếu bạn muốn sắp xếp bằng cách chỉ sử dụng number_of_viewsapproved_2 chìa khóa, thay đổi:

KEY `approved_2` (`approved`,`public_private`,`number_of_views`) 

tới:

KEY `approved_2` (`number_of_views`,`approved`,`public_private`) 

phím composite trong MySQL làm việc từ trái sang phải. Trong ví dụ trên, phím tuyên bố sử dụng number_of_views, approvedpublic_private implicity tạo chỉ số trên:

  • number_of_views
  • number_of_views, approved
  • number_of_views, approved, public_private
+0

Giải pháp này sẽ chỉ mất 'MySQL' khả năng lọc trên hai trường đầu tiên và sắp xếp trên trường thứ ba. – Quassnoi

+0

Anh ấy hỏi tại sao chỉ mục này không được sử dụng để sắp xếp. –

+1

Chỉ mục bạn đang đề xuất chỉ có thể được sử dụng để sắp xếp. Chỉ mục được đề xuất bởi '@ op' có thể được sử dụng để lọc * và * để sắp xếp. Không thể sử dụng chỉ mục của bạn để lọc, nhưng có thể (hoặc có thể không) được sử dụng để sắp xếp. – Quassnoi

0

này nên làm việc :

`select * from videos where approved='yes' and public_private='public' order by number_of_views desc;` 

Tf không, chỉ cần tạo một chỉ mục riêng biệt trên number_of_views.

Điều này phải hoạt động.

(mysql sau dãy bên trái bên phải cơ bản. Vì vậy, chỉ số của bạn trên approved, public_private, number_of_views sẽ không hoạt động nếu không được sử dụng theo thứ tự này. Ví dụ, bạn có thể sử dụng tất cả ba từ trái, 2 từ trái hoặc bên trái nhất 1 Nhưng nó sẽ không có tác dụng nếu bạn không sử dụng cái ngoài cùng bên trái, đó là ý tưởng.)

tự động, có thể giúp bạn trong order by - điều này tôi chắc chắn.

+0

chỉ thêm chỉ mục 'number_of_views' sẽ không giải quyết được vấn đề vì chỉ mục đó sẽ được xem là đáp ứng điều kiện' where'. Trong câu trả lời của OP, chỉ mục 'approved_2' nên được sử dụng và không lập chỉ mục trên' approved, public_private' và trên 'number_of_views' riêng biệt. –

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