2011-10-26 79 views
5

我有一個包含5或6個左連接的mysql查詢。正如所料,這很慢。考慮到我只希望達到100個結果,對我來說運行大量單獨的sql查詢並手動將它們拼接在一起可能更有意義。我猜這是因爲用多個左連接創建的巨大表需要很長時間。是對的嗎?使用LEFT JOIN提高性能

我在Rails 3中這樣做。我知道創建活動記錄的代價很高,但我認爲它可能比擁有這麼多的左連接更快。我對數據庫如何在隱藏條件下工作知之甚少。真的很感激任何見解。


編輯:這是實際的查詢和表模式

查詢

選擇people * FROM people LEFT JOIN person_organization_relationships ON person_organization_relationships .person_id = people .ID和 person_organization_relationships。 stop_person IS NULL LEFT JOIN person_redirect_relationships AS r_from_others ON r_from_others.parent_id = people .ID和r_from_others.stop_person IS NULL LEFT JOIN person_redirect_relationships AS r_to_others ON r_to_others.child_id = people .ID和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 AND r_p_check.stop_person IS NULL LEFT JOIN organization_redirect_relationships AS r_o_check ON r_o_check.child_id = person_organization_relationships .organization_id AND r_o_check.stop_organization IS NULL LEFT JOIN person_organization_relationships AS rr_p_check ON rr_p_check.person_id = r_from_others.child_i d與 rr_p_check.stop_person IS NULL LEFT JOIN organization_redirect_relationships AS rr_o_check ON rr_p_check.organization_id = rr_o_check.child_id AND rr_o_check.stop_organization IS NULL WHERE (((person_organization_relationships .organization_id = 1 OR r_o_check.parent_id = 1)AND r_to_others .parent_id IS NULL)OR (r_p_check.organization_id = 1 OR rr_o_check.parent_id = 1))GROUP BY people .ID

表架構:

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" 

此查詢不會產生任何結果。

+ ---- + ------------- + ------------------------ ----------- + -------- + ----------------------------- -------------------------------------------------- --------------------------------------- + ---------- --------------------------------------------- + ---- ----- + -------------------------------------------- ---------------------------- + ------ + -------------- ------------------- + | id | select_type |表| |鍵入| possible_keys
|鍵| key_len | ref
|行|額外| + ---- + ------------- + ----------------------------- ------ + -------- + ---------------------------------- -------------------------------------------------- ---------------------------------- + --------------- ---------------------------------------- + --------- + ------------------------------------------------- ----------------------- + ------ + ------------------- -------------- + | 1 | SIMPLE | person_details | ALL | index_person_details_on_current_p_id
| NULL | NULL | NULL
| 4938 |使用臨時;使用filesort | | 1 | SIMPLE |人 | 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 |使用where | + ---- + ------------- + ----------------------------- ------ + -------- + ---------------------------------- -------------------------------------------------- ---------------------------------- + --------------- ---------------------------------------- + --------- + ------------------------------------------------- ----------------------- + ------ + ------------------- -------------- + 9行集(0.00秒)

但是,當我運行查詢它花了0.14秒。這是很長一段時間嗎?我試圖找出在實現memcached之前是否有好的查詢。

+4

實際的查詢和EXPLAIN輸出將是有用的信息位。 –

+0

我同意@JoeStefanelli。向我們展示'EXPLAIN'的查詢+結果。 – Tadeck

回答

3

可能有多種原因。查詢性能差,索引不良等等。解釋,查詢,甚至可能爲所討論的表創建表語句將會幫助您找到答案。

大多數時候,當我看到這種東西的時候,這是一個索引很差的問題。

7

如此多的JOIN可能是一個非常糟糕的主意,但您應該首先顯示您的查詢。

首先,索引需要加快查詢速度。如果你沒有,你可能應該創建一些(取決於你執行的查詢)。

如果你做了多個LEFT JOIN,那麼你可以(可能)將它們分成不同的查詢,這應該使應用程序工作得更快。

您可以參考MySQL's documentation on optimization,特別是LEFT JOIN optimizationoptimization using indexes。這可能會給你更多的細節。

+0

好的答案,我只想強調,在這些類型的場景中,糟糕的索引使用是導致性能不佳的最可能原因。 –