Медленная MariaDB, когда Query присоединяется к миллиону записей - PullRequest
0 голосов
/ 16 февраля 2020

Я установил плагин и провел оптимизацию на бэкэнде (SSD, индексация по одному столбцу для столбцов, вызываемых в GROUP BY & WHERE), но при выполнении этого запроса

SELECT  u.user_id, u.profile_page_id, u.server_id AS user_server_id, u.user_name, u.full_name, u.gender, u.user_image, u.is_invisible, u.user_group_id, u.language_id, u.birthday, u.country_iso, m.*
FROM(
(SELECT m.*
FROM phpfox_channel_video AS m
INNER JOIN phpfox_channel_category AS mc
    ON(mc.category_id = mc.category_id)
INNER JOIN phpfox_channel_category_data AS mcd
    ON(mcd.video_id = m.video_id)

WHERE m.in_process = 0 AND m.view_id = 0 AND m.module_id = 'videochannel' AND m.item_id = 0 AND m.privacy IN(0) AND mcd.category_id = 17
GROUP BY m.video_id
ORDER BY m.time_stamp DESC
)) AS m
JOIN phpfox_user AS u
    ON(u.user_id = m.user_id)

ORDER BY m.time_stamp DESC
LIMIT 24;

это занимает 20 секунд вместо этого вместо этого

SELECT  u.user_id, u.profile_page_id, u.server_id AS user_server_id, u.user_name, u.full_name, u.gender, u.user_image, u.is_invisible, u.user_group_id, u.language_id, u.birthday, u.country_iso, m.*
FROM(
(SELECT  m.*
FROM phpfox_channel_video AS m
INNER JOIN phpfox_channel_category_data AS mcd
    ON(mcd.video_id = m.video_id AND mcd.category_id = 17)
WHERE m.in_process = 0 AND m.view_id = 0 AND m.module_id = 'videochannel' AND m.item_id = 0 AND m.privacy IN(0) 
GROUP BY m.video_id
ORDER BY m.time_stamp DESC
)) AS m
JOIN phpfox_user AS u
    ON(u.user_id = m.user_id)

ORDER BY m.time_stamp DESC
LIMIT 24;

Это работает около 5-6 секунд

. phpfox_channel_video содержит 2 миллиона строк (и будет продолжать быстро добавлять его, его сайт в социальных сетях и пользователь может загружать файлы тоже), поэтому кэширование не совсем полезно (но активировано).

Есть какие-нибудь советы, как это оптимизировать? У меня минимальный опыт работы с MariaDB / MySQL, так как я привык к MS SQL для больших данных и создания собственной структуры. Любой рекомендуемый метод, не требующий значительного изменения таблиц (добавление таблиц в порядке).

Или мне нужно реструктурировать таблицу PHP &, чтобы оптимизировать запрос так, чтобы он был ниже 1 секунды / запрос. Спасибо!

Я нашел эти ссылки http://mysql.rjweb.org/doc.php/memory & http://mysql.rjweb.org/doc.php/ricksrots#indexing

Они все еще актуальны?

прилагается это результаты объяснения enter image description here А что касается индекса, текущая конфигурация настроена так, чтобы индексировать каждый столбец, указанный как ключ индекса, все все таблицы, задействованные в запросе выше.

Будет ли полезна распечатка моей текущей конфигурации сервера? Спасибо!

Ответы [ 2 ]

0 голосов
/ 23 февраля 2020
INNER JOIN  phpfox_channel_category AS mc ON(mc.category_id = mc.category_id)

Является почти бесполезным.

  • Вы не используете никакие столбцы mc для других целей.
  • This JOIN
  • Этот JOIN проверил наличие соответствующей строки в mc.
  • Этот JOIN будет раздувать временную таблицу, если имеется , кратное соответствующие строки.
  • Раздувание приводит к напрасной работе в GROUP BY.

Аналогично, ваш второй запрос не использует mcd.

Пожалуйста, используйте разные псевдонимы для производных таблиц. Трудно следовать множественному использованию m..

Это абсолютно бесполезно:

ORDER BY  m.time_stamp DESC

MySQL / MariaDB может игнорировать ORDER BY в производной таблице. Таблица определена как набор неупорядоченных строк . Заказ можно выполнить только в конце.

Рекомендуемый индекс

m: INDEX(item_id, module_id, view_id, in_process, -- any order; tested with '='
         privacy,   -- sometimes has a list?
         video_id)  -- last
mcd:  INDEX(category_id, video_id)  -- in either order

Существует более логичный способ сделать это и, возможно, быстрее:

    INNER JOIN  phpfox_channel_category_data AS mcd
          ON  mcd.video_id = m.video_id
         AND  mcd.category_id = 17

Удалить и удалите GROUP BY m.id, затем добавьте это к WHERE:

AND EXISTS( SELECT 1 FROM phpfox_channel_category_data AS mcd
               WHERE  mcd.video_id = m.video_id
                 AND  mcd.category_id = 17 )

(Указанный выше индекс все еще применяется.)

Не то чтобы я, возможно, исключил два " «Сортировка файлов» - для GROUP BY и ORDER BY. Еще одно замечание: EXPLAIN не всегда показывает, сколько на самом деле файловых сортировок. (Но EXPLAIN FORMAT=JSON SELECT ... делает.)

0 голосов
/ 18 февраля 2020

Мне удалось очистить запрос, после проверки таблицы выясняется, что

WHERE m.in_process = 0
  AND m.view_id = 0
  AND m.module_id = 'videochannel'
  AND m.item_id = 0
  AND m.privacy IN(0) 

Не нужно запускать, потому что вся таблица соответствует этому условию .. (для текущего случая этого сайта) .. Так что я просто оптимизирую эти длинные запросы. И ударить <1 секунды сейчас .. </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...