MySQL GroupWise Максимальные проблемы производительности на столе для миллиона строк

StackOverflow https://stackoverflow.com//questions/11709712

Вопрос

Я пытаюсь найти простой способ улучшить производительность для очень активных форумов, где существует огромное количество сообщений, и MySQL больше не может делать в памяти таблицы в памяти, и, похоже, не в полном объеме индексов. < / P >.

Этот простой запрос находит самое последнее сообщение в каждой теме для пользователя, чтобы определить, есть ли у них какие-либо ответы, поскольку (позже сравнение TOPIC_TIME)

SELECT p.*, MAX(post_time) as post_time FROM forum_posts AS p   
WHERE p.poster_id = '1' AND p.post_status = '0' 
GROUP BY p.topic_id  
ORDER BY post_time DESC 
LIMIT 50
.

Простой, плоский стол выглядит что-то вроде

post_id | poster_id | topic_id | post_status | post_time | post_text
.

Однако это производительность распадается, когда есть миллион постов, и сами пользователь имеют десятки тысяч постов. MySQL может больше не сортировать таблицу в памяти, либо есть слишком много строк, чтобы сканировать. Это может занять до 3 секунд в использовании реального мира, что неприемлемо ИМХО, потому что он пробивает ЦП в течение этого времени и замедления всех остальных.

Я могу сделать любую комбинацию индекса конечно, но MySQL, похоже, в основном нравится использовать комбинацию

poster_id + post_time 
.

Так что он просто выбирает посты на 50 тысяч человек одного пользователя, а затем запускает группировку по TOPIC_ID и сортировке. Странно добавление topic_id в индексную смесь, похоже, не помогает производительности, хотя это может быть порядок полей индекса?

Я пытался написать эквивалентное соединение вместо этого, чтобы я мог использовать более одного индекса, но я столкнулся с проблемами с тем, что каждая сторона должна быть отфильтрована по post_status и плакат.

Я думал, что это будет быстрее, по крайней мере, для первых немногих страниц, если MySQL можно сделать, чтобы сначала сортировать данные через это индекс по Post_time, а затем начните выбирать отчетливый Topic_id для пользователя в убывании заказывать. Я предполагаю, что потребует подзапросе, и не уверена, что подзвездовый призыц 50K будет лучше, все еще нуждается в временной таблице.

Конечно, фундаментальное решение было бы увеличение дизайна основного ядра, чтобы существует еще одна таблица, которая просто хранит Max Post_time для каждого пользователя в каждой теме, но это слишком большое изменение, если ни один другой раствор не найден.

Спасибо за какие-либо предложения!


<Сильные> Добавление примера RealWorld и объясните:

<Сильный> медленный журнал

# Query_time: 2.751334  Lock_time: 0.000056 Rows_sent: 40  Rows_examined: 48286
SELECT   p.*, MAX(post_time) as post_time FROM forum_posts AS p   WHERE p.poster_id = '2' AND p.post_status = '0' GROUP BY p.topic_id  ORDER BY post_time DESC LIMIT 7000, 40;
.

<Сильные> Объясните

select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
SIMPLE          p   ref poster_time poster_time 4   const   27072   Using where; Using temporary; Using filesort
.

Это было полезно?

Решение

Во-первых, исправьте ваш запрос, чтобы предоставить результаты определения:

SELECT p.topic_id, 
       MAX(post_time) as post_time 
FROM forum_posts AS p   
WHERE p.poster_id = '1' AND p.post_status = '0' 
GROUP BY p.topic_id  
ORDER BY post_time DESC 
  LIMIT 50 ;
.

Затем попробуйте добавить индекс на (post_status, poster_id, topic_id, post_time).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top