Simon Peyou
Simon Peyou

Reputation: 703

Unable to FORCE INDEX on LEFT JOIN subquery?

I have a complicated query which involves a subquery inside a LEFT JOIN statement. The process time is ~2s. If I replace the subquery with a temporary table, I hit the same ~2s. If I create an index in the temporary table, I have ~0.05s.

I am trying to figure out why I can't work with Mysql USE INDEX or FORCE INDEX directly in the LEFT JOIN STATEMENT.

Here is a simple query which will return a 'check your mysql syntax' error.

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);

Why can't I use a FORCE INDEX with a LEFT JOIN subquery?

--edit: here is the actual query returning mysql error

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;

Upvotes: 2

Views: 4859

Answers (1)

bobwienholt
bobwienholt

Reputation: 17610

Why the subquery? Try this:

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

You probably won't even need to force the index with the above query.

Upvotes: 2

Related Questions