Reputation: 2063
I'm using MySQL 5.5. I have these 3 tables: News, NewsSubTopic, SubTopic. I wonder why this query is slow:
SELECT
DISTINCT COUNT(news0_.id) as col_0_0_
FROM
news news0_
INNER JOIN
news_sub_topic subtopics1_
ON
news0_.id = subtopics1_.news_sub_topics_id
INNER JOIN
sub_topic subtopic2_
ON
subtopics1_.sub_topic_id = subtopic2_.id
WHERE
(subtopic2_.id IN (55 , 134 , 135 , 52 , 53 , 32 , 54))
AND news0_.type = 'api';
I already placed index key in news.type. Is it possible to add keys in NewsSubTopic?
Here are some stats: News table has 1,088,126 entries, NewsSubTopic has 823,247 entries, and SubTopic has 168.
Note that that query is generated by a Grails (or Hibernate). Can you please explain on how to debug the query and understand why it is slow (3-5 seconds)? And is there any other way to improve it (I can provide other info that you need).
Upvotes: 2
Views: 159
Reputation: 5421
I don't understand why you are doing this:
...
ON
news0_.id = subtopics1_.news_sub_topics_id
Wouldn't NEWS.id be its PK and wouldn't there be another column like NEWS.topicid that you'd want to use when joining to topics?
You could try to cull the subtopics first:
select distinct newssubtopicid from newssubtopic as NS
inner join subtopic ST on NS.subtopicid = ST.id
and ST.id in (55 , 134 , 135 , 52 , 53 , 32 , 54)
ST.id is its PK, no? There should be an index on NS.subtopicid. How long does the above query take?
At that point you know which news subtopics you need for pulling the relevant news items:
select count(NEWS.id) from NEWS
inner join
(
select distinct newssubtopicid from newssubtopic as NS
inner join subtopic ST on NS.subtopicid = ST.id
and ST.id in (55 , 134 , 135 , 52 , 53 , 32 , 54)
) as T
on NEWS.topicid = T.newssubtopicid
Upvotes: 0
Reputation: 5661
Despite what has already been said, your query might be not Sargable. You will need to create indexes for your join conditions to make you query as less sensitive to the news_sub_topics_id as possible.
Make sure to use very selective indexes too (order your index fields by selectivity (VerySelective, LessSelective, ...).
Upvotes: 1
Reputation: 425683
You don't need DISTINCT
, arguments to COUNT
or a reference to sub_topic
:
SELECT COUNT(*)
FROM news_sub_topic ns
JOIN news n
ON n.id = ns.news_sub_topics_id
WHERE ns.sub_topic_id IN (55 , 134 , 135 , 52 , 53 , 32 , 54)
AND n.type = 'api'
Create a composite index on news_sub_topic (sub_topic_id, news_sub_topics_id)
Note that DISTINCT COUNT(…)
and COUNT(DISTINCT …)
are the different things. If you need the latter, use this:
SELECT COUNT(DISTINCT n.id)
FROM news_sub_topic ns
JOIN news n
ON n.id = ns.news_sub_topics_id
WHERE ns.sub_topic_id IN (55 , 134 , 135 , 52 , 53 , 32 , 54)
AND n.type = 'api'
Could you please explain what do you want to do with your query?
Upvotes: 4