2

LEFT JOIN ステートメント内にサブクエリを含む複雑なクエリがあります。処理時間は約 2 秒です。サブクエリを一時テーブルに置き換えると、同じ ~2 秒になります。一時テーブルにインデックスを作成すると、~0.05 秒になります。

LEFT JOIN ステートメントで Mysql USE INDEX または FORCE INDEX を直接操作できない理由を理解しようとしています。

これは、「mysql 構文を確認してください」というエラーを返す簡単なクエリです。

SELECT * 
FROM table1 t1 
LEFT JOIN (SELECT id_project FROM table2) t2 
FORCE INDEX FOR JOIN (id_project) 
   ON (t2.id_project = t1.id_project);

LEFT JOIN サブクエリで FORCE INDEX を使用できないのはなぜですか?

--edit: mysql エラーを返す実際のクエリは次のとおりです。

SELECT  
    p.id_projet, pa.piste_affaire, ty.type, p.e_force, gr.groupe, p.client, p.intitule_affaire, 
    ag.agence, st.statut, p.winratio, p.justification_nogo, p.webdoc, sp.sponsor, dis.domain_is, 
    cons.constructeur, p.date_chgt_statut, p.date_creation, 
    p.ca_estimatif, p.tcv, p.marge,
    tarp.target_price, p.marketable_price, 
    p.remise_propal_initiale, p.remise_propal_reel,
    p.date_de_signature, p.debut_build, p.fin_build,
    his.date, his.login, co.contrat, 
    p.duree_contrat, p.fqp, cap.capitalisation, 
    p.international, p.risk_management, p.asi, 
    GROUP_CONCAT(com.commentaire,',') AS COMMENT

FROM  
    piste_affaire pa, statut st, TYPE ty, agence ag, 
    domain_is dis, sponsor sp, constructeur cons, groupe gr, 
    target_price tarp, contrat co, historique his, capitalisation cap, 
    projet p 
    LEFT JOIN commentaire com ON (p.id_projet=com.id_projet)
    LEFT JOIN bizdev bizd  ON (p.id_bizdev = bizd.id_bizdev )
    LEFT JOIN (SELECT eco_projet.id_projet, 
                GROUP_CONCAT(
                CONCAT(ecosysteme) 
                ORDER BY ecosysteme SEPARATOR ', ' ) AS ecosysteme
                FROM ecosysteme NATURAL JOIN eco_projet, projet 
                WHERE eco_projet.id_projet = projet.id_projet  
                GROUP BY eco_projet.id_projet) AS tmpeco 
                /* if I delete that line, everything works as intended with ~2s query*/
                FORCE INDEX FOR JOIN (id_projet) 
                /* ** */
        ON (tmpeco.id_projet = p.id_projet)

WHERE 
    ag.id_division != 2 AND
    dis.id_division != 2 AND
    st.id_division != 2 AND
    pa.id_division != 2 AND 
    cons.id_division != 2 AND 
    p.type_division = 1 AND 
    pa.id_piste_affaire = p.id_piste_affaire AND
    p.id_statut = st.id_statut AND
    p.id_type = ty.id_type AND
    p.id_agence = ag.id_agence AND
    p.id_domain_is = dis.id_domain_is AND
    p.id_sponsor = sp.id_sponsor AND
    p.id_constructeur = cons.id_constructeur AND
    p.id_groupe = gr.id_groupe AND
    p.id_target_price = tarp.id_target_price AND
    p.id_contrat = co.id_contrat AND
    p.id_projet = his.id_projet AND
    p.id_capitalisation = cap.id_capitalisation 
GROUP BY p.id_projet;
4

1 に答える 1

2

なぜサブクエリ?これを試して:

SELECT * 
FROM table1 t1 
LEFT JOIN table2 t2 
FORCE INDEX FOR JOIN (id_project) 
ON (t2.id_project = t1.id_project);

おそらく、上記のクエリでインデックスを強制する必要さえないでしょう。

于 2012-10-08T14:17:44.517 に答える