Как улучшить SQL-запрос с JOIN? - PullRequest
2 голосов
/ 27 апреля 2011

Я использую MySQL 5.5.У меня есть эти 3 таблицы: Новости, NewsSubTopic, SubTopic.Интересно, почему этот запрос медленный:

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

Я уже поместил индексный ключ в news.type.Можно ли добавить ключи в NewsSubTopic?

Вот некоторые статистические данные: таблица новостей имеет 1 088 126 записей, NewsSubTopic имеет 823 247 записей, а SubTopic имеет 168 .

Обратите внимание, что этот запрос генерируется Grails (или Hibernate).Не могли бы вы объяснить, как отлаживать запрос и понять, почему он медленный (3-5 секунд)?И есть ли другой способ улучшить его (я могу предоставить другую информацию, которая вам нужна).

Ответы [ 3 ]

4 голосов
/ 27 апреля 2011

Вам не нужны DISTINCT, аргументы для COUNT или ссылка на 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'

Создание составного индекса для news_sub_topic (sub_topic_id, news_sub_topics_id)

Обратите внимание, чтоDISTINCT COUNT(…) и COUNT(DISTINCT …) - это разные вещи.Если вам нужно последнее, используйте это:

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'

Не могли бы вы объяснить, что вы хотите сделать с вашим запросом?

1 голос
/ 27 апреля 2011

Несмотря на то, что уже было сказано, ваш запрос может быть не Sargable .Вам нужно будет создать индексы для ваших условий соединения, чтобы сделать ваш запрос как можно менее чувствительным к news_sub_topics_id.

Убедитесь, что вы тоже используете очень селективные индексы (упорядочивайте поля индекса по селективности (VerySelective, LessSelective,...).

0 голосов
/ 27 апреля 2011

Я не понимаю, почему вы это делаете:

        ...
        ON
        news0_.id = subtopics1_.news_sub_topics_id

Не будет ли NEWS.id его ПК и не будет ли другой столбец, например NEWS.topicid, который вы захотите использовать при присоединении к темам?

Вы можете сначала попытаться отбросить подтемы:

            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 - это его ПК, нет? Должен быть указатель на NS.subtopicid. Сколько времени занимает приведенный выше запрос?

В этот момент вы знаете, какие новостные подтемы вам нужны для получения соответствующих новостей:

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