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