Mysql 使用左联接和按顺序排序时如何避免文件排序

Mysql 使用左联接和按顺序排序时如何避免文件排序,mysql,join,sql-order-by,filesort,Mysql,Join,Sql Order By,Filesort,我有3个表:accounts、contacts和accounts\u contacts映射表。 我在每个表中都有大约一百万条记录。此查询正在使用filesort,运行时间超过一分钟: explain SELECT contacts.salutation salutation, contacts.first_name first_name, contacts.last_name last_name, contacts.title title, jt0_accounts.id account_id,

我有3个表:accounts、contacts和accounts\u contacts映射表。 我在每个表中都有大约一百万条记录。此查询正在使用filesort,运行时间超过一分钟:

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   
如您所见,contacts表正在contacts表上使用filesort

我尝试通过在ORDER by之前添加WHERE jt0_accounts.name来摆脱filesort,使其成为:

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;
idx\u account\u contact索引由account\u id和contacts\u id组成。我尝试将它们添加到WHERE子句中,但似乎没有任何区别

如有任何建议,将不胜感激。
谢谢。

对于您的查询,您可能无能为力。但是,如果将查询更改为使用内部联接,则可能有机会:

SELECT c.salutation, c.first_name, c.last_name, c.title,
       a.id as account_id, a.name as account_name
FROM accounts a JOIN
     accounts_contacts ac
     ON a.id = ac.account_id AND a.deleted = 0
     contacts c JOIN
     ON c.id = ac.contact_id AND ac.deleted = 0     
ORDER BY a.name DESC;

然后,尝试以下索引:accountsname,deleted,id,accounts\u contacts account\u id,contact\u id,和concats contact\u id,deleted。

除非我弄错了,否则我认为使用内部联接对我不起作用。因为我想显示联系人表中的所有记录,即使它没有关联的帐户。内部联接的性能很好。我可以在原始查询中将LEFT替换为INNER,并很快得到结果。但结果并不是我所期望的。
SELECT c.salutation, c.first_name, c.last_name, c.title,
       a.id as account_id, a.name as account_name
FROM accounts a JOIN
     accounts_contacts ac
     ON a.id = ac.account_id AND a.deleted = 0
     contacts c JOIN
     ON c.id = ac.contact_id AND ac.deleted = 0     
ORDER BY a.name DESC;