백만 개의 행 테이블에 MySQL GroupWise 최대 성능 문제
-
13-12-2019 - |
문제
나는 거대한 수의 게시물이있는 매우 적극적인 포럼을위한 성능을 향상시키는 직접적인 방법을 찾고 있습니다. / 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은 더 이상 테이블을 메모리에서 정렬 할 수 없거나 스캔 할 행이 너무 많습니다. 해당 시간 동안 CPU를 스파이크하고 다른 모든 사람들을 늦추고 다른 모든 사람들을 늦추므로 인용 할 수없는 IMHO에서는 사용할 수없는 IMHO에서 최대 3 초가 걸릴 수 있습니다.
물론 색인을 조합 할 수 있지만 MySQL은 주로
의 콤보를 사용하고 싶습니다.poster_id + post_time
.
단지 하나의 사용자의 50K 게시물을 백만에서 선택한 다음 TOPIC_ID 및 정렬을 통해 그룹화를 시작합니다. topic_ID를 이상하게 추가하는 것은 인덱스 필드의 순서가 될 수 있지만 인덱스 믹스에 topic_id가 성능을 돕는 것 같지 않습니다.
나는 하나 이상의 인덱스를 사용할 수 있지만, 각 측면이 post_status 및 포스터에 의해 필터링되어야한다는 사실에 문제가 있음을 대신 해당 조인을 작성하려고 시도했다.
MySQL은 먼저 POST_TIME에 의해 인덱스를 통해 데이터를 정렬하고 내림차순으로 사용자를 위해 고유 한 TOPIC_ID를 선택하기 시작하면 최소한 몇 페이지의 경우 최소한 몇 페이지의 경우 더 빨라질 수 있다고 생각했습니다. 주문. 나는 하위 쿼리가 필요할 것이고 50K 결과 하위 쿼리가 더 좋을 것이라고 확신 할 수 없을 것으로 추측하고, 임시 테이블이 필요합니다.
물론 기본 솔루션은 각 주제에서 각 사용자마다 최대 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)
에 인덱스를 추가 한 후 시도해보십시오.