【发布时间】:2023-03-30 00:47:01
【问题描述】:
我有 3 个表:accounts、contacts 和 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
如您所见,联系人表正在使用联系人表上的文件排序。
我尝试通过在“ORDER BY”之前添加“WHERE jt0_accounts.name ''”来摆脱文件排序,因此它变为:
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 子句中,但似乎没有任何区别。
任何建议将不胜感激。 谢谢。
【问题讨论】:
标签: mysql join sql-order-by filesort