0

与えられた SQL は 1.2 秒かかります:

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  

私は明確にする必要があり、すべての結合を残す必要があり、順序付けが必要であり、制限が必要です。
どうにかして最適化できますか?

4

4 に答える 4

0

これらは私が持っている唯一の提案です

  1. ID が主キーとして定義され、外部キーがテーブル間の関係で定義されることを願っています。

  2. おそらく、application_number にインデックスを付けることができます (その後、ソートが高速になります)

  3. おそらく、MyISAM を使用している場合は、選択する前にテーブルをロックすると、SQL が高速になる可能性があります (後でロックを解除することを忘れないでください)。

于 2013-04-16T10:18:06.737 に答える
0

最初に、次の列に必要なインデックスを作成します。

contract.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

あなたが言及したように、あなたはすでにcontracts.deletedのインデックスを持っています

FROM 
  (SELECT * FROM contracts WHERE contracts.deleted = 0 USE INDEX(<deletedIndexName>))
LEFT JOIN 
  accounts jt0 
ON 
  jt0.id = contracts.account_id
LEFT JOIN  
  ...
于 2013-04-16T10:30:40.683 に答える