鉴于SQL需要1.2s:
SELECT DISTINCT contracts.id, jt0.id, jt1.id, jt2.id, jt3.id FROM contracts
LEFT JOIN accounts jt0 ON jt0.id = contracts.account_id AND jt0.deleted=0
LEFT JOIN manufacturers jt1 ON jt1.id = contracts.manufacturer_id AND jt1.deleted=0
LEFT JOIN products jt2 ON jt2.id = contracts.product_id AND jt2.deleted=0
LEFT JOIN users jt3 ON jt3.id = contracts.assigned_user_id AND jt3.deleted=0
WHERE contracts.deleted=0
ORDER BY contracts.application_number ASC
LIMIT 0,21
这是解释扩展回报的原因:
id select_type table type possible_keys key key_len ref rows
1 SIMPLE contracts ref idx_contracts_deleted idx_contracts_deleted 2 const 18968 100.00 Using where; Using temporary; Using filesort
1 SIMPLE jt0 eq_ref PRIMARY,idx_accnt_id_del,idx_accnt_assigned_del PRIMARY 108 xxx.contracts.account_id 1 100.00
1 SIMPLE jt1 eq_ref PRIMARY,idx_manufacturers_id_deleted,idx_manufacturers_deleted PRIMARY 108 xxx.contracts.manufacturer_id 1 100.00
1 SIMPLE jt2 eq_ref PRIMARY,idx_products_id_deleted,idx_products_deleted PRIMARY 108 xxx.contracts.product_id 1 100.00
1 SIMPLE jt3 eq_ref PRIMARY,idx_users_id_del,idx_users_id_deleted,idx_users_deleted PRIMARY 108 xxx.contracts.assigned_user_id 1 100.00
我需要与众不同,我需要留下所有的联接,我需要订购,我需要限制 我能以某种方式对其进行优化吗?
答案 0 :(得分:0)
这是我唯一的建议
我希望id被定义为主键和外键与表之间的关系。
也许可以索引application_number(然后排序会更快)
也许,如果您使用MyISAM,如果您在选择之前锁定表格(不要忘记之后解锁),则SQL可能会更快
答案 1 :(得分:0)
首先在以下列中创建必要的索引。
contracts.application_number,manufacturers.deleted,products.deleted,users.deleted
SELECT DISTINCT contracts.id, jt0.id, jt1.id, jt2.id, jt3.id
FROM contracts
LEFT JOIN accounts jt0
ON contracts.deleted=0 AND jt0.id = contracts.account_id
LEFT JOIN manufacturers jt1
ON jt1.deleted=0 AND jt1.id = contracts.manufacturer_id
LEFT JOIN products jt2
ON jt2.deleted=0 AND jt2.id = contracts.product_id
LEFT JOIN users jt3
ON jt3.deleted=0 AND jt3.id = contracts.assigned_user_id
ORDER BY contracts.application_number ASC
LIMIT 0,21
正如您所提到的,您已经在contract.deleted
上编制了索引FROM
(SELECT * FROM contracts WHERE contracts.deleted = 0 USE INDEX(<deletedIndexName>))
LEFT JOIN
accounts jt0
ON
jt0.id = contracts.account_id
LEFT JOIN
...
答案 2 :(得分:0)
尝试更改子表上的索引以包含deleted
列:
accounts(id, deleted)
manufacturers(id, deleted)
products(id, deleted)
users(id, deleted)
通过在索引中包含所有列,MySQL可以更好地利用索引。
另一个建议是找出导致值重复的原因,并使用子查询来消除重复,而不是distinct
。
例如,使用以上索引:
from contracts c left join
(select id
from accounts
where deleted = 0
group by id
) a
on c.account_id = a.id
. . .
子查询应该只使用索引,这可能会加快速度。
答案 3 :(得分:0)
尝试一点参考完整性?我敢打赌,内部联接的查询速度要快得多。它应该是,因为查询优化器有更多的工作。您需要在select
时付费,因为create
没有更多关注。
我还会删除已删除的行到他们自己的表中,并点击deleted
列。您的查询将更简单,并且可能运行得更快。