2011-05-06 1 views
1

Je ne sais pas si c'est possible, mais si c'est le cas, ma requête serait beaucoup plus rapide.Passer le résultat d'une sous-requête à une clause IN dans une autre sous-requête dans MySQL

Fondamentalement, j'ai une question comme ceci:

SELECT * 
    FROM (SELECT bar.id 
      FROM pivot_table 
      WHERE foo.id = x) t1 
    JOIN (SELECT count(*) c1, bar.id 
      FROM table 
     GROUP BY bar.id) t2 ON t1.id = t2.id 
    JOIN (SELECT count(*) c2, bar.id 
      FROM another_table 
     GROUP BY bar.id) t3 ON t1.id = t3.id 

Mais cela est assez lent parce table et another_table sont énormes. Mais vraiment je ne suis intéressé que par les valeurs résultant de la requête en t1. Donc, si je pouvais en quelque sorte obtenir ces résultats dans une clause IN pour t2 et t3 la requête devrait accélérer de manière significative.

Est-ce possible?


Pas trop clair je suppose. OK ce que je pensais que changer la requête à quelque chose comme:

SELECT * 
    FROM (GROUP_CONCAT (bar.id) as results 
       FROM pivot_table 
       WHERE foo.id = x) t1 
     JOIN (SELECT count(*) c1, bar.id 
       FROM table 
       WHERE bar.id IN (*results from t1*) 
       GROUP BY bar.id) t2 ON t1.id = t2.id 
     JOIN (SELECT count(*) c2, bar.id 
       FROM another_table 
       WHERE bar.id IN (*results from t1*) 
       GROUP BY bar.id) t3 ON t1.id = t3.id 

pourrait être plus rapide car il se rétrécit vers le bas le nombre de lignes numérisées t2 et t3. Cela ne serait-il pas le cas?


Tout le monde veut le voir, voici donc la requête complète:

SELECT (k_group.count/jk_group.count) * (s_group.count/jk_group.count) AS ratio, 
     jk_group.k_id               , 
     jk_group.s_id 
FROM 
     -- find the keywords for the job 
     (SELECT jk.keyowrd_id AS k_id 
     FROM jobs_keywords jk 
     WHERE job_id = 50100 
     ) 
     extracted_keywords 
     -- calculate the necessary values using group_by functions 
     INNER JOIN 
        (SELECT COUNT(*) count, 
          skill_id AS s_id , 
          keyword_id AS k_id 
        FROM  jobs_keywords jk 
          JOIN jobs_skills js 
          ON  js.job_id = jk.job_id 
          JOIN job_feed_details d 
          ON  d.job_id = js.job_id 
        WHERE d.moderated  = 1 
        GROUP BY skill_id, 
          keyword_id 
       ) 
        jk_group 
     ON  extracted_keywords.k_id = jk_group.k_id 
     INNER JOIN 
        (SELECT COUNT(*)  count, 
          keyword_id AS k_id 
        FROM  jobs_keywords jk 
          JOIN job_feed_details d 
          ON  d.job_id = js.job_id 
        WHERE d.moderated  = 1 
        GROUP BY keyword_id 
       ) 
        k_group 
     ON  jk_group.k_id = k_group.k_id 
     INNER JOIN 
        (SELECT COUNT(*) count, 
          skill_id AS s_id 
        FROM  jobs_skills js 
          JOIN job_feed_details d 
          ON  d.job_id = js.job_id 
        WHERE d.moderated  = 1 
        GROUP BY skill_id 
       ) 
        s_group 
     ON  jk_group.s_id = s_group.s_id 
ORDER BY ratio DESC 
LIMIT 25 
+1

Pas de sens - pourquoi utiliser des fonctions d'agrégation (COUNT) si vous voulez seulement vérifier l'existence de l'ID dans les tables de support? Beaucoup de fautes de frappe, btw, aussi. S'il vous plaît poster les colonnes (et les tables dont ils proviennent) que vous voulez comme résultat final. –

+0

Votre deuxième requête est presque identique à la première requête à l'exception du Group_Concat. Vous pourriez nous aider en révisant les requêtes pour qu'elles puissent être compilées. Par exemple, 'foo.id' et' bar.id' dans la table dérivée T1 ne fonctionnera pas. En outre, cela ne nous aide pas lorsque vous utilisez 'bar.id' dans une sous-requête ultérieure. – Thomas

+0

Est-ce que 'job_id, keyword_id' est unique dans job_keywords? Est-ce que 'job_id, skill_id' est unique dans job_skills? – Thomas

Répondre

1

j'ai pu accomplir ce que je voulais faire comme ceci:

SELECT * 
    FROM (@var:=GROUP_CONCAT(bar.id) as results 
       FROM pivot_table 
       WHERE foo.id = x) t1 
     JOIN (SELECT count(*) c1, bar.id 
       FROM table 
       WHERE bar.id IN (@var) 
       GROUP BY bar.id) t2 ON t1.id = t2.id 
     JOIN (SELECT count(*) c2, bar.id 
       FROM another_table 
       WHERE bar.id IN (@var) 
       GROUP BY bar.id) t3 ON t1.id = t3.id 

Mais les avantages en termes de vitesse ne sont pas trop importants. J'ai maintenant abandonné l'approche de requête unique en faveur de beaucoup de petites requêtes, et c'est beaucoup mieux.

0

Révision donné requête réelle

Je pense que vous pouvez rogner votre requête vers le bas pour:

Select jk.Count(Distinct jk.keyword_id) 
     * jk.Count(Distinct js.skill_id) 
     /Power(Count(*), 2) 
     As ratio 
    , js.skill_id 
    , jk.keyword_id 
From jobs_keywords As jk 
    Join jobs_skills As js 
     On js.job_id = jk.job_id 
Where jk.job_id =50100 
Group By js.skill_id, jk.keyword_id 
Order By ratio Desc 
Limit 25 
1
SELECT COUNT(t1.id) c1, COUNT(t2.id) c2, COUNT(t3.id) c3, t1.id 
FROM pivot_table t1 
JOIN table t2 ON t1.id=t2.id 
JOIN another_table t3 ON t3.id=t1.id where t1.id=x group by t1.id 

pls assurez-vous que le pivot_table.id, table.id et another_table.id sont indexés

au sujet de votre requête: le problème de votre requête est la table driverd utilisation joindre tampon, pour rendre votre requête rapide, vous devez augmenter votre rejoindre la taille du tampon

Questions connexes