2009-03-12 23 views
6

Tôi đang cố tối ưu hóa truy vấn sử dụng chế độ xem trong MySQL 5.1. Dường như ngay cả khi tôi chọn 1 cột từ chế độ xem, nó luôn quét toàn bộ bảng. Đó có phải là hành vi mong đợi không?Chế độ xem MySQL có luôn quét toàn bộ bảng không?

Chế độ xem chỉ là một "Tất cả các cột từ các bảng này - KHÔNG *" cho các bảng mà tôi đã chỉ định trong truy vấn đầu tiên bên dưới.

Đây là kết quả giải thích của tôi khi tôi chọn cột được chỉ mục PromotionID từ truy vấn tạo nên chế độ xem. Như bạn có thể thấy nó rất khác với đầu ra trên màn hình.

EXPLAIN SELECT pb.PromotionID FROM PromotionBase pb INNER JOIN PromotionCart pct ON pb.PromotionID = pct.PromotionID INNER JOIN PromotionCode pc ON pb.PromotionID = pc.PromotionID WHERE pc.PromotionCode = '5TAFF312C0NT'\G; 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: pc 
     type: const 
possible_keys: PRIMARY,fk_pc_pb 
      key: PRIMARY 
     key_len: 302 
      ref: const 
     rows: 1 
     Extra: 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: pb 
     type: const 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: const 
     rows: 1 
     Extra: Using index 
*************************** 3. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: pct 
     type: const 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: const 
     rows: 1 
     Extra: Using index 
3 rows in set (0.00 sec) 

Sản lượng khi tôi chọn điều tương tự nhưng từ quan điểm

EXPLAIN SELECT vpc.PromotionID FROM vw_PromotionCode vpc WHERE vpc.PromotionCode = '5TAFF312C0NT'\G; 
*************************** 1. row *************************** 
      id: 1 
    select_type: PRIMARY 
     table: <derived2> 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 5830 
     Extra: Using where 
*************************** 2. row *************************** 
      id: 2 
    select_type: DERIVED 
     table: pcart 
     type: index 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: NULL 
     rows: 33 
     Extra: Using index 
*************************** 3. row *************************** 
      id: 2 
    select_type: DERIVED 
     table: pb 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: readyinteractive.pcart.PromotionID 
     rows: 1 
     Extra: 
*************************** 4. row *************************** 
      id: 2 
    select_type: DERIVED 
     table: pc 
     type: ref 
possible_keys: fk_pc_pb 
      key: fk_pc_pb 
     key_len: 4 
      ref: readyinteractive.pb.PromotionID 
     rows: 249 
     Extra: Using where 
*************************** 5. row *************************** 
      id: 3 
    select_type: UNION 
     table: pp 
     type: index 
possible_keys: PRIMARY 
      key: pp_p 
     key_len: 4 
      ref: NULL 
     rows: 1 
     Extra: Using index 
*************************** 6. row *************************** 
      id: 3 
    select_type: UNION 
     table: pb 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: readyinteractive.pp.PromotionID 
     rows: 1 
     Extra: 
*************************** 7. row *************************** 
      id: 3 
    select_type: UNION 
     table: pc 
     type: ref 
possible_keys: fk_pc_pb 
      key: fk_pc_pb 
     key_len: 4 
      ref: readyinteractive.pb.PromotionID 
     rows: 249 
     Extra: Using where 
*************************** 8. row *************************** 
      id: 4 
    select_type: UNION 
     table: pcp 
     type: index 
possible_keys: PRIMARY 
      key: pcp_cp 
     key_len: 4 
      ref: NULL 
     rows: 1 
     Extra: Using index 
*************************** 9. row *************************** 
      id: 4 
    select_type: UNION 
     table: pb 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: readyinteractive.pcp.PromotionID 
     rows: 1 
     Extra: 
*************************** 10. row *************************** 
      id: 4 
    select_type: UNION 
     table: pc 
     type: ref 
possible_keys: fk_pc_pb 
      key: fk_pc_pb 
     key_len: 4 
      ref: readyinteractive.pb.PromotionID 
     rows: 249 
     Extra: Using where 
*************************** 11. row *************************** 
      id: 5 
    select_type: UNION 
     table: ppc 
     type: index 
possible_keys: PRIMARY 
      key: ppc_pc 
     key_len: 4 
      ref: NULL 
     rows: 1 
     Extra: Using index 
*************************** 12. row *************************** 
      id: 5 
    select_type: UNION 
     table: pb 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: readyinteractive.ppc.PromotionID 
     rows: 1 
     Extra: 
*************************** 13. row *************************** 
      id: 5 
    select_type: UNION 
     table: pc 
     type: ref 
possible_keys: fk_pc_pb 
      key: fk_pc_pb 
     key_len: 4 
      ref: readyinteractive.pb.PromotionID 
     rows: 249 
     Extra: Using where 
*************************** 14. row *************************** 
      id: 6 
    select_type: UNION 
     table: ppt 
     type: index 
possible_keys: PRIMARY 
      key: ppt_pt 
     key_len: 4 
      ref: NULL 
     rows: 1 
     Extra: Using index 
*************************** 15. row *************************** 
      id: 6 
    select_type: UNION 
     table: pb 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: readyinteractive.ppt.PromotionID 
     rows: 1 
     Extra: 
*************************** 16. row *************************** 
      id: 6 
    select_type: UNION 
     table: pc 
     type: ref 
possible_keys: fk_pc_pb 
      key: fk_pc_pb 
     key_len: 4 
      ref: readyinteractive.pb.PromotionID 
     rows: 249 
     Extra: Using where 
*************************** 17. row *************************** 
      id: NULL 
    select_type: UNION RESULT 
     table: <union2,3,4,5,6> 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: NULL 
     Extra: 
17 rows in set (0.18 sec) 

Trả lời

9

Lần trong MySQL không được lập chỉ mục như vậy bởi bản chất của họ đòi hỏi phải có đầy đủ quét mỗi khi họ được truy cập. Nói chung điều này làm cho Views thực sự chỉ hữu ích cho các tình huống mà bạn có một truy vấn tĩnh khá phức tạp mà trả về một tập hợp kết quả nhỏ và bạn định lấy toàn bộ tập hợp kết quả mỗi lần.

Chỉnh sửa: Tất nhiên Chế độ xem sẽ sử dụng chỉ mục trên bảng bên dưới để Chế độ xem được tối ưu hóa (nếu không chúng sẽ không có ý nghĩa gì cả), nhưng không có chỉ mục trên Chế độ xem không thể cho truy vấn WHERE trên Chế độ xem được tối ưu hóa.

Xây dựng chỉ mục cho Chế độ xem sẽ đắt tiền bởi vì trong khi tôi không cố gắng cấu hình bất kỳ Chế độ xem nào, tôi khá chắc chắn rằng bảng tạm thời được tạo đằng sau hậu trường và sau đó kết quả được trả về. Nó đã mất rất nhiều thời gian để xây dựng bảng tạm thời, tôi sẽ không muốn một cái nhìn mà cũng cố gắng để đoán những gì chỉ số là cần thiết. Mà sẽ trả về điểm thứ hai đó là MySQL hiện không cung cấp một phương thức để chỉ định các chỉ mục nào để sử dụng cho một khung nhìn để làm sao nó biết được các trường nào cần được lập chỉ mục? Liệu nó có dựa trên truy vấn của bạn không?

Bạn có thể xem xét sử dụng Temporary Table vì sau đó bạn có thể chỉ định chỉ mục trên các trường trong bảng tạm thời. Tuy nhiên, từ kinh nghiệm này có xu hướng thực sự, rất chậm.

Nếu tất cả chế độ xem này chứa là SELECT ALL FROM table1, table2, table3; sau đó tôi sẽ phải hỏi tại sao truy vấn này cần phải ở trong Chế độ xem? Nếu vì lý do nào đó, bạn có thể muốn sử dụng một thủ tục được lưu trữ để đóng gói truy vấn khi bạn có thể nhận được hiệu suất tối ưu trong khi vẫn duy trì lợi ích của một cuộc gọi đơn giản tới cơ sở dữ liệu cho tập kết quả.

+0

Nó nói ở đây http://dev.mysql.com/doc/refman/5.0/en/view-restrictions.html rằng chế độ xem sẽ sử dụng các chỉ mục của các bảng cơ bản. – Alex

+0

Tôi khá chắc chắn bạn là đúng - truy vấn trên quan điểm MySQL có thể sử dụng các chỉ mục từ các bảng nguồn của nó.Bạn chỉ không thể có một chỉ mục trên chính khung nhìn đó và do đó không thể có một chỉ mục duy nhất chứa các cột từ nhiều hơn một trong các bảng đó. – thomasrutter

+0

Thật không may là không giải thích tại sao truy vấn thứ hai đó được tối ưu hóa kém bởi MySQL. Tất cả những gì tôi có thể nghĩ là có lẽ quan điểm đó không chính xác tham gia theo cách nó được dự định. Không biết mặc dù. – thomasrutter

3

Tôi đã xem xét kỹ hơn về nó, tôi đã bỏ lỡ một điểm quan trọng của thông tin: (Truy vấn xem của tôi thực sự có liên kết với một bảng khác. Điều này làm cho chế độ xem sử dụng thuật toán TEMPORARY TABLE thay vì thuật toán MERGE

. các thuật toán TABLE TẠM không cho phép việc sử dụng các chỉ số trong bảng bên dưới.

này có vẻ là một lỗi trong MySQL và đã được báo cáo cách trở lại trong năm 2006 nhưng không giống như nó đã được được giải quyết trong năm 2009! http://forums.mysql.com/read.php?100,56681,56681

Có vẻ như tôi sẽ chỉ phải ghi lại truy vấn dưới dạng bản tóm tắt r tham gia.

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