#mysql #sql
#mysql #sql
Вопрос:
Не уверен, возможно ли это, но если это так, это сделало бы мой запрос намного быстрее.
В принципе, у меня есть запрос, подобный этому:
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
предложение for 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
Комментарии:
1. Не имеет смысла — зачем использовать агрегированные функции (COUNT), если вы хотите только проверить наличие идентификатора в вспомогательных таблицах? Кстати, тоже много опечаток. Пожалуйста, опубликуйте столбцы (и таблицы, из которых они взяты), которые вы хотите получить в качестве конечного результата.
2. Ваш второй запрос почти идентичен первому запросу, за исключением Group_Concat. Вы могли бы помочь нам, изменив запросы, чтобы они компилировались. Например,
foo.id
иbar.id
в производной таблице T1 не будут работать. Кроме того, это не помогает нам при использованииbar.id
в более позднем подзапросе.3.
job_id,keyword_id
Является уникальным в job_keywords?job_id, skill_id
Является уникальным в job_skills?4. @thomas для них есть уникальный ключ, да.
Ответ №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
пожалуйста, убедитесь, что pivot_table.id, table.id и another_table.идентификаторы индексируются
о вашем запросе: проблема вашего запроса в том, что таблица driverd использует буфер соединения, чтобы ускорить ваш запрос, вам следует увеличить размер буфера соединения
Ответ №2:
Я смог выполнить то, что я пытался сделать, вот так:
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
Но преимущества с точки зрения скорости были не слишком значительными. Теперь я отказался от подхода с одним запросом в пользу множества меньших запросов, и это намного лучше.
Ответ №3:
Доработка с учетом фактического запроса
Я думаю, вы можете сократить свой запрос до:
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