>데이터 베이스 >MySQL 튜토리얼 >각 사용자의 최신 행을 효율적으로 검색하기 위해 GROUP BY 쿼리를 최적화하려면 어떻게 해야 합니까?

각 사용자의 최신 행을 효율적으로 검색하기 위해 GROUP BY 쿼리를 최적화하려면 어떻게 해야 합니까?

DDD
DDD원래의
2025-01-24 00:37:14276검색

How Can I Optimize GROUP BY Queries to Efficiently Retrieve the Latest Row for Each User?

사용자별 최신 행을 검색하기 위한 GROUP BY 쿼리의 최적화 전략

log_date, user_id 및 페이로드로 구성된 사용자 메시지가 포함된 테이블 제공 , 작업은 특정 시간 이전에 각 사용자의 최신 기록을 효율적으로 검색하는 것입니다. date.

다중 열 인덱스

읽기 성능을 향상하려면 user_id 및 log_date에 다중 열 인덱스를 생성하세요.

CREATE INDEX log_combo_idx ON log (user_id, log_date DESC NULLS LAST);

Index- 포함 색인이 있는 스캔만

인덱스 전용 스캔의 경우 페이로드 열을 포함하는 포함 인덱스를 정의합니다.

CREATE INDEX log_combo_covering_idx ON log (user_id, log_date DESC NULLS LAST) INCLUDE (payload);

SELECT DISTINCT ON()

작은 테이블 또는 user_id당 몇 개의 행의 경우, SELECT DISTINCT ON()을 사용하는 것이 효율적일 수 있습니다.

SELECT DISTINCT ON(user_id) log_date, payload
FROM log
WHERE log_date <= :mydate
ORDER BY user_id, log_date DESC;

색인 건너뛰기 스캔 에뮬레이션

user_id당 행이 많은 대규모 테이블의 경우 LATERAL 조인이 포함된 재귀 CTE를 사용하여 인덱스 건너뛰기 스캔을 에뮬레이션하는 것이 좋습니다.

WITH RECURSIVE cte AS (
   (
   SELECT user_id, log_date, payload
   FROM   log
   WHERE  log_date <= :mydate
   ORDER  BY user_id, log_date DESC NULLS LAST
   LIMIT  1
   )
   UNION ALL
   SELECT l.*
   FROM   cte c
   CROSS  JOIN LATERAL (
      SELECT l.user_id, l.log_date, l.payload
      FROM   log l
      WHERE  l.user_id > c.user_id  -- lateral reference
      AND    log_date <= :mydate    -- repeat condition
      ORDER  BY l.user_id, l.log_date DESC NULLS LAST
      LIMIT  1
      ) l
   )
TABLE  cte
ORDER  BY user_id;

별도의 사용자 테이블

별도의 사용자 테이블이 존재하는 경우 단순화된 솔루션은 가능:

LATERAL 조인

SELECT u.user_id, l.log_date, l.payload
FROM   users u
CROSS  JOIN LATERAL (
   SELECT l.log_date, l.payload
   FROM   log l
   WHERE  l.user_id = u.user_id         -- lateral reference
   AND    l.log_date <= :mydate
   ORDER  BY l.log_date DESC NULLS LAST
   LIMIT  1
   ) l;

상관 하위 쿼리

SELECT user_id, (combo1).*              -- note parentheses
FROM (
   SELECT u.user_id
        , (SELECT (l.log_date, l.payload)::combo
           FROM   log l
           WHERE  l.user_id = u.user_id
           AND    l.log_date <= :mydate
           ORDER  BY l.log_date DESC NULLS LAST
           LIMIT  1) AS combo1
   FROM   users u
   ) sub;

이러한 최적화는 인덱스를 활용하여 쿼리 성능을 향상시킵니다. , 건너뛰기 스캔 에뮬레이션 및 사용자를 위한 별도의 테이블 활용 정보입니다.

위 내용은 각 사용자의 최신 행을 효율적으로 검색하기 위해 GROUP BY 쿼리를 최적화하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.