2011-10-26 46 views
5

Tôi có truy vấn mysql có 5 hoặc 6 THAM GIA TRÁI. Đúng như dự đoán, điều này khá chậm. Xem xét rằng tôi chỉ mong đợi ~ 100 kết quả, có thể nó có ý nghĩa hơn cho tôi để chạy rất nhiều truy vấn sql riêng biệt và tự khâu chúng lại với nhau. Tôi đoán rằng nó mất một thời gian dài vì bảng lớn được tạo ra với nhiều phép nối trái. Có đúng không?Cải thiện hiệu suất với LEFT JOIN

Tôi đang làm điều này trong Rails 3. Tôi biết rằng việc tạo hồ sơ hoạt động là tốn kém, nhưng tôi cho rằng nó có thể nhanh hơn so với có rất nhiều LEFT JOINS. Tôi biết rất ít về cách cơ sở dữ liệu hoạt động dưới mui xe. Sẽ thực sự đánh giá cao bất kỳ thông tin chi tiết nào.


Edit: Đây là các truy vấn và bảng schemas thực tế

Query

CHỌN people * FROM people LEFT JOIN person_organization_relationships ON person_organization_relationships .person_id = people .id VÀ person_organization_relationships.. stop_person IS NULL LEFT JOIN person_redirect_relationships AS r_from_others ON r_from_others.parent_id = people .id VÀ r_from_others.stop_person LÀ NULL LEFT JOIN person_redirect_relationships AS r_to_others ON r_to_others.child_id = people .id VÀ r_to_others.stop_person IS NULL LEFT JOIN person_organization_relationships AS r_p_check ON r_p_check.person_id = r_from_others. child_id VÀ r_p_check.stop_person LÀ tRÁI NULL THAM GIA organization_redirect_relationships AS r_o_check ON r_o_check.child_id = person_organization_relationships .organization_id VÀ r_o_check.stop_organization IS NULL LEFT THAM GIA person_organization_relationships AS rr_p_check ON rr_p_check.person_id = r_from_others.child_i d VÀ rr_p_check.stop_person LÀ TRÁI NULL THAM GIA organization_redirect_relationships AS rr_o_check ON rr_p_check.organization_id = rr_o_check.child_id VÀ rr_o_check.stop_organization IS NULL ĐÂU (((person_organization_relationships .organization_id = 1 HOẶC r_o_check.parent_id = 1) VÀ r_to_others .parent_id IS NULL) HOẶC (r_p_check.organization_id = 1 HOẶC rr_o_check.parent_id = 1)) GROUP BY people .id

schema Bảng:

create_table "people", :force => true do |t| 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.boolean "delta",    :default => true, :null => false 
    end 


    create_table "person_organization_relationships", :force => true do |t| 
    t.integer "person_id" 
    t.integer "organization_id" 
    t.integer "start_person" 
    t.integer "stop_person" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    add_index "person_organization_relationships", ["organization_id"], :name => "index_person_organization_relationships_on_organization_id" 
    add_index "person_organization_relationships", ["person_id"], :name => "index_person_organization_relationships_on_person_id" 
    add_index "person_organization_relationships", ["start_person"], :name => "index_person_organization_relationships_on_start_person" 
    add_index "person_organization_relationships", ["stop_person"], :name => "index_person_organization_relationships_on_stop_person" 

    create_table "person_redirect_relationships", :force => true do |t| 
    t.integer "parent_id" 
    t.integer "child_id" 
    t.integer "start_person" 
    t.integer "stop_person" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    add_index "person_redirect_relationships", ["child_id"], :name => "index_person_redirect_relationships_on_child_id" 
    add_index "person_redirect_relationships", ["parent_id"], :name => "index_person_redirect_relationships_on_parent_id" 
    add_index "person_redirect_relationships", ["start_person"], :name => "index_person_redirect_relationships_on_start_person" 
    add_index "person_redirect_relationships", ["stop_person"], :name => "index_person_redirect_relationships_on_stop_person" 


    create_table "organization_redirect_relationships", :force => true do |t| 
    t.integer "parent_id" 
    t.integer "child_id" 
    t.integer "start_organization" 
    t.integer "stop_organization" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    add_index "organization_redirect_relationships", ["child_id"], :name => "index_organization_redirect_relationships_on_child_id" 
    add_index "organization_redirect_relationships", ["parent_id"], :name => "index_organization_redirect_relationships_on_parent_id" 
    add_index "organization_redirect_relationships", ["start_organization"], :name => "index_organization_redirect_relationships_on_start_organization" 
    add_index "organization_redirect_relationships", ["stop_organization"], :name => "index_organization_redirect_relationships_on_stop_organization" 

Truy vấn này không mang lại kết quả nào.

+ ---- + ------------- + ------------------------ ----------- + -------- + ----------------------------- -------------------------------------------------- --------------------------------------- + ---------- --------------------------------------------- + ---- ----- + -------------------------------------------- ---------------------------- + ------ + -------------- ------------------- + | id | select_type | bảng | loại | possible_keys
| khóa | key_len | ref
| hàng | Thêm | + ---- + ------------- + ----------------------------- ------ + -------- + ---------------------------------- -------------------------------------------------- ---------------------------------- + --------------- ---------------------------------------- + --------- + ------------------------------------------------- ----------------------- + ------ + ------------------- -------------- + | 1 | SIMPLE | person_details | TẤT CẢ | index_person_details_on_current_p_id
| NULL | NULL | NULL
| 4938 | Sử dụng tạm thời; Sử dụng filesort | | 1 | SIMPLE | người | eq_ref | PRIMARY
| PRIMARY | 4 | knolcano_development.person_details.current_p_id
| 1 | | | 1 | SIMPLE | person_organization_relationships | ref | index_person_organization_relationships_on_person_id, index_person_organization_relationships_on_stop_person | index_person_organization_relationships_on_person_id | 5 | knolcano_development.person_details.current_p_id
| 1 | | | 1 | SIMPLE | r_from_others | ref | index_person_redirect_relationships_on_parent_id, index_person_redirect_relationships_on_stop_person | index_person_redirect_relationships_on_stop_person | 5 | const
| 3 | | | 1 | SIMPLE | r_to_others | ref | index_person_redirect_relationships_on_child_id, index_person_redirect_relationships_on_stop_person | index_person_redirect_relationships_on_child_id | 5 | knolcano_development.people.id
| 2 | | | 1 | SIMPLE | r_p_check | ref | index_person_organization_relationships_on_person_id, index_person_organization_relationships_on_stop_person | index_person_organization_relationships_on_person_id | 5 | knolcano_development.r_from_others.child_id
| 1 | | | 1 | SIMPLE | r_o_check | ref | index_organization_redirect_relationships_on_child_id, index_organization_redirect_relationships_on_stop_organization | index_organization_redirect_relationships_on_child_id | 5 | knolcano_development.person_organization_relationships.organization_id | 1 | | | 1 | SIMPLE | rr_p_check | ref | index_person_organization_relationships_on_person_id, index_person_organization_relationships_on_stop_person | index_person_organization_relationships_on_person_id | 5 | knolcano_development.r_from_others.child_id
| 1 | | | 1 | SIMPLE | rr_o_check | ref | index_organization_redirect_relationships_on_child_id, index_organization_redirect_relationships_on_stop_organization | index_organization_redirect_relationships_on_child_id | 5 | knolcano_development.rr_p_check.organization_id
| 1 | Sử dụng ở đâu | + ---- + ------------- + ----------------------------- ------ + -------- + ---------------------------------- -------------------------------------------------- ---------------------------------- + --------------- ---------------------------------------- + --------- + ------------------------------------------------- ----------------------- + ------ + ------------------- -------------- + 9 hàng trong bộ (0,00 giây)

Nhưng khi tôi chạy truy vấn mất 0,14 giây. Đó có phải là một khoảng thời gian dài không? Tôi đang cố gắng tìm ra nếu tôi có các truy vấn tốt trước khi tôi thực hiện memcached.

+4

Truy vấn thực tế và đầu ra GIẢI THÍCH sẽ là các thông tin hữu ích. –

+0

Tôi đồng ý với @JoeStefanelli. Hiển thị cho chúng tôi truy vấn + kết quả của 'EXPLAIN'. – Tadeck

Trả lời

3

Có thể có một số lý do cho việc này. Hiệu suất truy vấn kém, chỉ mục xấu, v.v. Giải thích, truy vấn và thậm chí có thể tạo các bảng câu lệnh cho các bảng được đề cập sẽ là một cách rất dài để giúp đưa ra câu trả lời.

Hầu hết thời gian khi tôi thấy loại điều này, mặc dù, đó là vấn đề của chỉ mục nghèo.

7

Vì vậy, nhiều JOIN có thể là một ý tưởng rất tồi, nhưng bạn nên hiển thị truy vấn của mình trước tiên.

Trước hết, chỉ mục được yêu cầu để tăng tốc truy vấn. Nếu bạn không có bất kỳ, bạn có thể nên tạo một số (tùy thuộc vào truy vấn bạn thực hiện).

Và nếu bạn làm nhiều LEFT JOIN, thì bạn có thể (có thể) tách chúng thành các truy vấn khác nhau và điều này sẽ làm cho ứng dụng hoạt động nhanh hơn rất nhiều.

Bạn có thể tham khảo MySQL's documentation on optimization, cụ thể là LEFT JOIN optimizationoptimization using indexes. Điều này có thể cung cấp cho bạn chi tiết bổ sung.

+0

Câu trả lời hay, tôi chỉ muốn nhấn mạnh rằng việc sử dụng chỉ mục xấu là nguyên nhân có khả năng gây ra hiệu suất kém nhất trong các loại kịch bản này. –

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