1.5M 행이있는 테이블에서 비교적 간단한 쿼리가 있습니다.
SELECT mtid FROM publication
WHERE mtid IN (9762715) OR last_modifier=21321
LIMIT 5000;
EXPLAIN ANALYZE
산출:
Limit (cost=8.84..12.86 rows=1 width=8) (actual time=0.985..0.986 rows=1 loops=1) -> Bitmap Heap Scan on publication (cost=8.84..12.86 rows=1 width=8) (actual time=0.984..0.985 rows=1 loops=1) Recheck Cond: ((mtid = 9762715) OR (last_modifier = 21321)) -> BitmapOr (cost=8.84..8.84 rows=1 width=0) (actual time=0.971..0.971 rows=0 loops=1) -> Bitmap Index Scan on publication_pkey (cost=0.00..4.42 rows=1 width=0) (actual time=0.295..0.295 rows=1 loops=1) Index Cond: (mtid = 9762715) -> Bitmap Index Scan on publication_last_modifier_btree (cost=0.00..4.42 rows=1 width=0) (actual time=0.674..0.674 rows=0 loops=1) Index Cond: (last_modifier = 21321) Total runtime: 1.027 ms
지금까지는 좋고 빠르며 사용 가능한 색인을 사용합니다.
이제 쿼리를 약간 수정하면 결과는 다음과 같습니다.
SELECT mtid FROM publication
WHERE mtid IN (SELECT 9762715) OR last_modifier=21321
LIMIT 5000;
EXPLAIN ANALYZE
출력은 다음과 같습니다
Limit (cost=0.01..2347.74 rows=5000 width=8) (actual time=2735.891..2841.398 rows=1 loops=1) -> Seq Scan on publication (cost=0.01..349652.84 rows=744661 width=8) (actual time=2735.888..2841.393 rows=1 loops=1) Filter: ((hashed SubPlan 1) OR (last_modifier = 21321)) SubPlan 1 -> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1) Total runtime: 2841.442 ms
너무 빠르지 않고 seq 스캔을 사용하는 중 ...
물론 응용 프로그램이 실행하는 원래 쿼리는 조금 더 복잡하고 느리며 최대 절전 모드로 생성 된 원본은 그렇지 (SELECT 9762715)
않지만 속도는 느려집니다 (SELECT 9762715)
! 쿼리는 최대 절전 모드에서 생성되므로 변경하기가 상당히 어려우며 일부 기능을 사용할 수 없습니다 (예 : UNION
사용할 수 없으므로 빠름).
질문
- 두 번째 경우에 색인을 사용할 수없는 이유는 무엇입니까? 그들은 어떻게 사용될 수 있습니까?
- 다른 방법으로 쿼리 성능을 향상시킬 수 있습니까?
추가 생각
SELECT를 수동으로 수행 한 다음 결과 목록을 쿼리에 넣어 첫 번째 경우를 사용할 수 있습니다. IN () 목록에 5000 개의 숫자가 있어도 두 번째 솔루션보다 4 배 빠릅니다. 그러나 그것은 잘못 된 것처럼 보입니다 (또한 100 배 빠를 수도 있습니다 :)). 쿼리 플래너가이 두 쿼리에 대해 완전히 다른 방법을 사용하는 이유를 완전히 이해할 수 없으므로이 문제에 대한 더 좋은 해결책을 찾고 싶습니다.
(SELECT 9762715)
있습니다.
(SELECT 9762715)
. 최대 절전 모드 질문 : 그것은 가능하지만 사용자가 정의한 최대 절전 모드 기준 쿼리가 즉석에서 번역되므로 심각한 코드 재 작성이 필요합니다. 따라서 본질적으로 우리는 가능한 많은 부작용을 가진 거대한 사업 인 최대 절전 모드를 수정합니다.
JOIN
에서IN ()
? 대신에 최대 절전 모드가 생성되도록 코드를 다시 작성할 수 있습니까 ? 또한publication
최근에 분석 되었습니까?