Как ускорить MYSQL Запрос с JOIN и между предложением где? - PullRequest
1 голос
/ 21 марта 2020

Запрос

SELECT SQL_CALC_FOUND_ROWS wp29174960179_posts.*
    FROM wp29174960179_posts
         JOIN wp29174960179_plugin_wpf_products_attribute_79_numbers pan ON pan.product_id = wp29174960179_posts.ID
    WHERE pan.number BETWEEN 10 and 10000
    ORDER BY wp29174960179_posts.post_date ASC LIMIT 0, 9; 

Этот запрос очень медленный (занимает 2 с) . Ожидаемое время выполнения <= 100 мс </strong>

Имеется 80 000 записей в wp29174960179_plugin_wpf_products_attribute_79_numbers таблица.

И 100 000 записей в wp29174960179_posts таблица

Есть 2 индекса для wp29174960179_plugin_wpf_products_attribute_79_numbers таблица

ix__number__product_id (product_id, number)
ix__product_id__number (number, product_id)

Существует индекс для *wp29174960179_posts для ID поле

Несмотря на эти индексы. Запрос занимает 2-3 секунды

SQL полная ссылка на фрагмент кода:

https://www.db-fiddle.com/f/4Vk97FhArBVJ1Eb1BAubNB/0# & Togetherjs = 8KQQacE4Vt

Ответы [ 2 ]

3 голосов
/ 21 марта 2020

Это выглядит как у вас есть отношения 1-N между сообщениями и панорамированием, и вы пытаетесь получить сообщения, для которых существуют строки в панораме, которые удовлетворяют заданному условию.

Если это так, вы можете попробовать переписать запрос с помощью подзапроса EXISTS:

select p.*
from wp29174960179_posts p
where exists (
    select 1 
    from wp29174960179_plugin_wpf_products_attribute_79_numbers n 
    where n.product_id = p.id and n.number between 10 and 10000
)
order by p.post_date 
limit 9

. Этот метод позволяет избежать необходимости агрегирования во внешнем запросе. Этот запрос должен иметь возможность использовать индекс на wp29174960179_plugin_wpf_products_attribute_79_numbers(product_id, number).

1 голос
/ 21 марта 2020

Я предполагаю, что внешняя сортировка вызывает проблемы с производительностью. Ваш запрос и индексы выглядят разумно. Вопрос в том, можем ли мы обмануть MySQL, чтобы избежать сортировки?

Начнем с переписывания, которое предлагает GMB. Это также имеет приятную характеристику c, что он не возвращает дублированные значения:

select p.*
from wp29174960179_posts p
where exists (select 1 
              from wp29174960179_plugin_wpf_products_attribute_79_numbers n 
              where n.product_id = p.id and
                    n.number between 10 and 10000
             )
order by p.post_date 
limit 9;

Затем попробуйте следующие индексы:

  • wp29174960179_posts(post_date, id)
  • wp29174960179_plugin_wpf_products_attribute_79_numbers(product_id, number)

Есть надежда, что таблица сообщений будет отсканирована в порядке post_date и будут возвращены первые 9 соответствующих строк. Скрестив пальцы.

...