0
我有3個表:帳戶,聯繫人和accounts_contacts(映射表)。 我在每張表中都有100萬條記錄。此查詢使用文件排序,並需要超過一分鐘,運行:如何避免使用左連接時的文件和
explain SELECT contacts.salutation salutation, contacts.first_name first_name, contacts.last_name last_name, contacts.title title, jt0_accounts.id account_id, jt0_accounts.name account_name
FROM contacts
LEFT JOIN accounts_contacts jt1_accounts_contacts ON (contacts.id = jt1_accounts_contacts.contact_id AND jt1_accounts_contacts.deleted = 0)
LEFT JOIN accounts jt0_accounts ON (jt0_accounts.id = jt1_accounts_contacts.account_id AND jt0_accounts.deleted = 0)
ORDER BY jt0_accounts.name DESC;
這是解釋輸出:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE contacts ALL NULL NULL NULL NULL 195634 Using temporary; Using filesort
1 SIMPLE jt1_accounts_contacts ref idx_contid_del_accid idx_contid_del_accid 113 sugar7.contacts.id,const 1
1 SIMPLE jt0_accounts eq_ref PRIMARY,idx_accounts_id_del,idx_accounts_date_entered,idx_accnt_assigned_del PRIMARY 108 sugar7.jt1_accounts_contacts.account_id 1
正如你所看到的,接觸表使用上的聯繫人表文件排序。
我試圖通過添加擺脫文件排序的「WHERE jt0_accounts.name <>'」前「ORDER BY」,所以它變成了:
explain SELECT contacts.salutation salutation, contacts.first_name first_name, contacts.last_name last_name, contacts.title title, jt0_accounts.id account_id, jt0_accounts.name account_name
FROM contacts
LEFT JOIN accounts_contacts jt1_accounts_contacts ON (contacts.id = jt1_accounts_contacts.contact_id AND jt1_accounts_contacts.deleted = 0)
LEFT JOIN accounts jt0_accounts ON (jt0_accounts.id = jt1_accounts_contacts.account_id AND jt0_accounts.deleted = 0)
WHERE jt0_accounts.name <> ''
ORDER BY jt0_accounts.name DESC;
它得到上擺脫了文件排序的聯繫人表,但它現在使用的文件排序的映射表:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE jt1_accounts_contacts ALL idx_account_contact,idx_contid_del_accid NULL NULL NULL 34994 Using where; Using temporary; Using filesort
1 SIMPLE jt0_accounts eq_ref PRIMARY,idx_accounts_id_del,idx_accounts_date_entered,idx_accnt_name_del,idx_accnt_assigned_del PRIMARY 108 sugar7.jt1_accounts_contacts.account_id 1 Using where
1 SIMPLE contacts eq_ref PRIMARY,idx_contacts_id_del,idx_contacts_date_entered PRIMARY 108 sugar7.jt1_accounts_contacts.contact_id 1 Using where
的idx_account_contact指數由ACCOUNT_ID和contacts_id的。我試着將它們添加到WHERE子句中,但它似乎沒有任何區別。
任何建議,將不勝感激。 謝謝。
除非我誤會,否則我不認爲使用內連接對我有效。因爲我想顯示聯繫人表中的所有記錄,即使它沒有關聯的帳戶。 – Formosan 2015-04-01 20:12:22
@Formosan。 。 。這個版本的性能如何? – 2015-04-01 22:21:04
內連接的性能很好。我可以用我最初的查詢中的「INNER」替換「LEFT」並立即得到結果。但結果不會是我所期望的。 – Formosan 2015-04-01 23:54:03