Передача результата из одного подзапроса в предложение IN в другом подзапросе в MySQL - PullRequest
1 голос
/ 06 мая 2011

Не уверен, что это возможно, но если это так, мой запрос будет выполняться намного быстрее.

По сути, у меня есть такой запрос:

 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

Но это довольно медленно, потому что table и another_table огромны. Но на самом деле меня интересуют только те значения, которые получены в результате запроса в t1. Поэтому, если бы я мог каким-то образом получить эти результаты в предложение IN для t2 и t3, запрос должен значительно ускориться.

Возможно ли это?


Не слишком ясно, я думаю. Хорошо, я думал, что изменив запрос на что-то вроде:

 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

Может быть быстрее, потому что это сужает количество строк, отсканированных в t2 и t3. Разве это не так?


Каждый хочет это увидеть, поэтому вот полный запрос:

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

Ответы [ 3 ]

1 голос
/ 06 мая 2011
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

Просьба убедиться, что pivot_table.id, table.id и another_table.id проиндексированы

о вашем запросе: проблема вашего запроса в том, что в таблице драйверов используется буфер соединения, чтобы сделать ваш запрос быстрым, вы должны увеличить размер буфера соединения

1 голос
/ 08 мая 2011

Мне удалось выполнить то, что я пытался сделать так:

 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

Но преимущества с точки зрения скорости были не слишком значительными. Теперь я отказался от подхода с одним запросом в пользу множества небольших запросов, и это намного лучше.

0 голосов
/ 06 мая 2011

Редакция с учетом фактического запроса

Я думаю, вы можете сократить свой запрос до:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...