Переписать запрос JOIN на подзапросы, пропущенные строки?

0

У меня есть следующий запрос MySQL, который возвращает эти строки:

SELECT p.ID AS id, p.post_title AS title, p.post_author AS uid, SUM(v.pageviews) AS pageviews, IFNULL(c.comment_count, 0) AS comment_count 
FROM 'views' v 
LEFT JOIN 'posts' p ON v.postid = p.ID 
LEFT JOIN (SELECT comment_post_ID, COUNT(comment_post_ID) AS comment_count FROM 'comments' WHERE comment_date_gmt > DATE_SUB('2018-08-16 18:34:46', INTERVAL 29 DAY) AND comment_approved = 1 GROUP BY comment_post_ID) c ON p.ID = c.comment_post_ID 
WHERE 1 = 1 AND p.post_type IN('post') AND v.view_datetime > DATE_SUB('2018-08-16 18:34:46', INTERVAL 29 DAY) AND p.post_password = '' AND p.post_status = 'publish' GROUP BY v.postid ORDER BY pageviews DESC LIMIT 5 OFFSET 0;

Изображение 174551

В настоящее время я пытаюсь переписать его с помощью подзапросов вместо JOINs, чтобы проверить, лучше ли производительность.

Следующий запрос возвращает те же результаты (за исключением столбца comment_count поскольку мы запрашиваем только две таблицы вместо трех):

SELECT p.ID AS id, p.post_title AS title, p.post_author AS uid, v.pageviews AS pageviews 
FROM 'posts' p,
    (SELECT SUM(pageviews) AS pageviews, postid FROM 'views' WHERE view_datetime > DATE_SUB( '2018-08-16 18:34:46', INTERVAL 29 DAY) GROUP BY postid) v
WHERE 1 = 1 AND p.ID = v.postid AND p.post_type IN('post') AND p.post_password = '' AND p.post_status = 'publish' GROUP BY v.postid ORDER BY pageviews DESC LIMIT 5 OFFSET 0

Изображение 174551

Однако, если я добавлю таблицу comments в микс, сообщения, которые не имеют комментариев, автоматически исключаются (например, ID 2956 с 3100 просмотров), возвращая другой результат по сравнению с исходным запросом:

SELECT p.ID AS id, p.post_title AS title, p.post_author AS uid, v.pageviews AS pageviews, IFNULL(c.comment_count, 0) AS comment_count 
FROM 'posts' p,
    (SELECT SUM(pageviews) AS pageviews, postid FROM 'views' WHERE view_datetime > DATE_SUB( '2018-08-16 18:34:46', INTERVAL 29 DAY) GROUP BY postid) v,
    (SELECT COUNT(comment_post_ID) AS comment_count, comment_post_ID FROM 'comments' WHERE comment_date_gmt > DATE_SUB('2018-08-16 18:34:46', INTERVAL 29 DAY) AND comment_approved = 1 GROUP BY comment_post_ID) c 
WHERE 1 = 1 AND p.ID = v.postid AND v.postid = c.comment_post_ID AND p.post_type IN('post') AND p.post_password = '' AND p.post_status = 'publish' GROUP BY v.postid ORDER BY pageviews DESC LIMIT 5 OFFSET 0

Изображение 174551

Я еще не настолько опытен с этим материалом (как вы можете сказать), поэтому любая помощь/подсказки, чтобы понять, что происходит, будет очень оценена.

  • 1
    Ваши новые запросы до сих пор соединения, но теперь они INNER JOIN и (вот что , значит) вместо ЛЕВЫЙ JOIN и , и дал вам иметь не ON состоянии Я ожидаю , что производительность будет намного хуже ...
  • 0
    Я также думаю, что так и будет, Ник, но я хочу быть на 100% уверенным (отсюда и причина, по которой я переписываю запрос). Спасибо за подсказку о INNER JOIN, я подозревал, что именно поэтому я получаю эти результаты, но я не был уверен. Я буду продолжать играть с запросом.
Теги:
subquery

1 ответ

1
Лучший ответ

Как я уже упоминал в своем комментарии, ваши новые запросы все еще имеют JOIN. Если вы хотите проверить производительность с помощью подзапросов, вам нужно изменить запрос на что-то вроде этого (это мое лучшее предположение, основанное на вашем исходном рабочем запросе, не видя структуры таблицы и данных, что трудно быть на 100%):

SELECT id, post_title AS title, post_author AS uid, 
    (SELECT SUM(pageviews) 
     FROM views v 
     WHERE v.postid = posts.id AND 
           v.view_datetime > DATE_SUB('2018-08-16 18:34:46', INTERVAL 29 DAY)
    ) AS pageviews,
    (SELECT COUNT(comment_post_ID) 
     FROM comments c 
     WHERE c.comment_post_ID = posts.id AND
           c.comment_date_gmt > DATE_SUB('2018-08-16 18:34:46', INTERVAL 29 DAY) AND 
           c.comment_approved = 1
    ) AS comment_count
FROM posts
WHERE p.post_type IN('post') AND p.post_password = '' AND p.post_status = 'publish'
ORDER BY pageviews DESC 
LIMIT 5 OFFSET 0;
  • 0
    Только что протестировал вашу версию, и она работает быстрее, чем моя оригинальная (0,02505 секунд против 0,05449 секунд, на 54,03% быстрее!). Я должен был включить некоторые примеры таблиц, но это, вероятно, сделало бы вопрос больше, чем нужно (я бы предоставил дамп .sql, если бы кто-то спросил). Спасибо за помощь!
  • 0
    Замечательно! Рад, что смог помочь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню