PostgreSQL에서 GIN 인덱스를 사용할 때 ORDER BY 정렬 속도를 높이는 방법은 무엇입니까?


13

나는 이와 같은 테이블을 가지고있다 :

CREATE TABLE products (
  id serial PRIMARY KEY, 
  category_ids integer[],
  published boolean NOT NULL,
  score integer NOT NULL,
  title varchar NOT NULL);

제품은 여러 범주에 속할 수 있습니다. category_ids열에는 모든 제품 카테고리의 ID 목록이 있습니다.

일반적인 검색어는 다음과 같습니다 (항상 단일 카테고리 검색).

SELECT * FROM products WHERE published
  AND category_ids @> ARRAY[23465]
ORDER BY score DESC, title
LIMIT 20 OFFSET 8000;

속도를 높이려면 다음 색인을 사용하십시오.

CREATE INDEX idx_test1 ON products
  USING GIN (category_ids gin__int_ops) WHERE published;

하나의 카테고리에 제품이 너무 많지 않으면 도움이됩니다. 해당 카테고리에 속하는 제품을 신속하게 필터링하지만 인덱스없이 어려운 방법으로 정렬 작업이 수행됩니다.

다음 btree_gin과 같이 다중 열 GIN 색인을 작성할 수 있도록 확장 기능 을 설치 했습니다.

CREATE INDEX idx_test2 ON products USING GIN (
  category_ids gin__int_ops, score, title) WHERE published;

그러나 Postgres는이를 정렬에 사용하고 싶지 않습니다 . DESC쿼리에서 지정자를 제거하더라도 .

작업을 최적화하기위한 다른 방법은 매우 환영합니다.


추가 정보:

  • 인타 레이 확장 기능이있는 PostgreSQL 9.4
  • 현재 총 제품 수는 260k이지만 크게 증가 할 것으로 예상됩니다 (최대 10M, 멀티 테넌트 전자 상거래 플랫폼 임)
  • 범주 당 제품 1..10000 (100k까지 증가 할 수 있음), 평균은 100 미만이지만 제품 수가 많은 범주는 더 많은 요청을 유도하는 경향이 있습니다.

다음 쿼리 계획은 더 작은 테스트 시스템 (선택한 카테고리의 4680 제품, 총 200k 제품)에서 얻은 것입니다.

Limit  (cost=948.99..948.99 rows=1 width=72) (actual time=82.330..82.341 rows=20 loops=1)
  ->  Sort  (cost=948.37..948.99 rows=245 width=72) (actual time=80.231..81.337 rows=4020 loops=1)
        Sort Key: score, title
        Sort Method: quicksort  Memory: 928kB
        ->  Bitmap Heap Scan on products  (cost=13.90..938.65 rows=245 width=72) (actual time=1.919..16.044 rows=4680 loops=1)
              Recheck Cond: ((category_ids @> '{292844}'::integer[]) AND published)
              Heap Blocks: exact=3441
              ->  Bitmap Index Scan on idx_test2  (cost=0.00..13.84 rows=245 width=0) (actual time=1.185..1.185 rows=4680 loops=1)
                    Index Cond: (category_ids @> '{292844}'::integer[])
Planning time: 0.202 ms
Execution time: 82.404 ms

참고 # 1 : 82ms는 두렵지 않지만 정렬 버퍼가 메모리에 맞기 때문입니다. 제품 테이블에서 모든 열을 선택하면 ( SELECT * FROM ...실제로 약 60 열이 있습니다) Sort Method: external merge Disk: 5696kB실행 시간 이 두 배가됩니다. 그리고 그것은 4680 제품에만 해당됩니다.

동작 지점 # 1 (주 # 1에서 제공) : 정렬 작업의 메모리 풋 프린트줄이고 약간 속도를 높이려면 먼저 제품 ID를 페치, 정렬 및 제한 한 다음 전체 레코드를 페치하는 것이 좋습니다.

SELECT * FROM products WHERE id IN (
  SELECT id FROM products WHERE published AND category_ids @> ARRAY[23465]
  ORDER BY score DESC, title LIMIT 20 OFFSET 8000
) ORDER BY score DESC, title;

이것은 Sort Method: quicksort Memory: 903kB4680 제품에 대해 ~ 80ms로 되돌아갑니다 . 제품 수가 100k로 증가하면 여전히 느려질 수 있습니다.


이 페이지에서 : hlinnaka.iki.fi/2014/03/28/… btree_gin 을 정렬에 사용할 수 없다는 의견이 있습니다.
Mladen Uzelac 2016 년

더 많은 옵션을 허용하기 위해 제목을 다시 정의했습니다.
Yaroslav Stavnichiy 2016 년

항상 단일 카테고리를 검색하고 있습니까? 그리고 Postgres 버전, 카디널리티, 범주 당 행 (분 / 평균 / 최대)과 같은 기본 정보를 제공하십시오. postgresql-performance 의 태그 정보에서 지침을 고려하십시오 . 그리고 : scoreNULL 일 수는 있지만 여전히,로 정렬 score DESC하지 않습니다 score DESC NULLS LAST. 하나 또는 다른 하나 옳지 않은 것 같습니다 ...
Erwin Brandstetter

요청에 따라 추가 정보를 추가했습니다. 나는 항상 단일 카테고리를 찾고 있습니다. 그리고 score실제로 NULL이 아닙니다-테이블 정의를 수정했습니다.
Yaroslav Stavnichiy 2016 년

답변:


10

나는 많은 실험을 해왔으며 여기에 나의 발견이 있습니다.

진과 분류

현재 GIN 지수 (버전 9.4 기준) 는 주문을 지원할 수 없습니다 .

현재 PostgreSQL에서 지원하는 인덱스 유형 중에서 B- 트리 만 정렬 된 출력을 생성 할 수 있습니다. 다른 인덱스 유형은 지정되지 않은 구현 종속 순서로 일치하는 행을 반환합니다.

work_mem

이 구성 매개 변수 를 지적 해 주신 Chris에게 감사 합니다 . 기본값은 4MB이며 레코드 세트가 더 큰 경우 work_mem적절한 값 (에서 찾을 수 있음)으로 증가 하면 EXPLAIN ANALYSE정렬 작업 속도가 크게 향상 될 수 있습니다 .

ALTER SYSTEM SET work_mem TO '32MB';

변경 사항을 적용하려면 서버를 다시 시작한 다음 다시 확인하십시오.

SHOW work_mem;

원래 검색어

데이터베이스를 650k 제품으로 채우고 일부 카테고리는 최대 40k 제품을 보유했습니다. published절 을 제거하여 쿼리를 약간 단순화했습니다 .

SELECT * FROM products WHERE category_ids @> ARRAY [248688]
ORDER BY score DESC, title LIMIT 10 OFFSET 30000;

Limit  (cost=2435.62..2435.62 rows=1 width=1390) (actual time=1141.254..1141.256 rows=10 loops=1)
  ->  Sort  (cost=2434.00..2435.62 rows=646 width=1390) (actual time=1115.706..1140.513 rows=30010 loops=1)
        Sort Key: score, title
        Sort Method: external merge  Disk: 29656kB
        ->  Bitmap Heap Scan on products  (cost=17.01..2403.85 rows=646 width=1390) (actual time=11.831..25.646 rows=41666 loops=1)
              Recheck Cond: (category_ids @> '{248688}'::integer[])
              Heap Blocks: exact=6471
              ->  Bitmap Index Scan on idx_products_category_ids_gin  (cost=0.00..16.85 rows=646 width=0) (actual time=10.140..10.140 rows=41666 loops=1)
                    Index Cond: (category_ids @> '{248688}'::integer[])
Planning time: 0.288 ms
Execution time: 1146.322 ms

우리가 볼 수있는 work_mem만큼 충분하지 않았기 때문에 Sort Method: external merge Disk: 29656kB(여기의 숫자는 대략적인 것으로, 인 메모리 퀵 정렬을 위해서는 32MB 이상이 필요합니다)

메모리 풋 프린트 감소

정렬을 위해 전체 레코드를 선택하지 않고 ID를 사용하고 정렬, 오프셋 및 제한을 적용한 다음 필요한 레코드를 10 개만로드하십시오.

SELECT * FROM products WHERE id in (
  SELECT id FROM products WHERE category_ids @> ARRAY[248688]
  ORDER BY score DESC, title LIMIT 10 OFFSET 30000
) ORDER BY score DESC, title;

Sort  (cost=2444.10..2444.11 rows=1 width=1390) (actual time=707.861..707.862 rows=10 loops=1)
  Sort Key: products.score, products.title
  Sort Method: quicksort  Memory: 35kB
  ->  Nested Loop  (cost=2436.05..2444.09 rows=1 width=1390) (actual time=707.764..707.803 rows=10 loops=1)
        ->  HashAggregate  (cost=2435.63..2435.64 rows=1 width=4) (actual time=707.744..707.746 rows=10 loops=1)
              Group Key: products_1.id
              ->  Limit  (cost=2435.62..2435.62 rows=1 width=72) (actual time=707.732..707.734 rows=10 loops=1)
                    ->  Sort  (cost=2434.00..2435.62 rows=646 width=72) (actual time=704.163..706.955 rows=30010 loops=1)
                          Sort Key: products_1.score, products_1.title
                          Sort Method: quicksort  Memory: 7396kB
                          ->  Bitmap Heap Scan on products products_1  (cost=17.01..2403.85 rows=646 width=72) (actual time=11.587..35.076 rows=41666 loops=1)
                                Recheck Cond: (category_ids @> '{248688}'::integer[])
                                Heap Blocks: exact=6471
                                ->  Bitmap Index Scan on idx_products_category_ids_gin  (cost=0.00..16.85 rows=646 width=0) (actual time=9.883..9.883 rows=41666 loops=1)
                                      Index Cond: (category_ids @> '{248688}'::integer[])
        ->  Index Scan using products_pkey on products  (cost=0.42..8.45 rows=1 width=1390) (actual time=0.004..0.004 rows=1 loops=10)
              Index Cond: (id = products_1.id)
Planning time: 0.682 ms
Execution time: 707.973 ms

참고 Sort Method: quicksort Memory: 7396kB. 결과가 훨씬 좋습니다.

가입 및 추가 B- 트리 색인

Chris가 조언했듯이 추가 색인을 만들었습니다.

CREATE INDEX idx_test7 ON products (score DESC, title);

먼저 다음과 같이 합류했습니다.

SELECT * FROM products NATURAL JOIN
  (SELECT id FROM products WHERE category_ids @> ARRAY[248688]
  ORDER BY score DESC, title LIMIT 10 OFFSET 30000) c
ORDER BY score DESC, title;

쿼리 계획이 약간 다르지만 결과는 같습니다.

Sort  (cost=2444.10..2444.11 rows=1 width=1390) (actual time=700.747..700.747 rows=10 loops=1)
  Sort Key: products.score, products.title
  Sort Method: quicksort  Memory: 35kB
  ->  Nested Loop  (cost=2436.05..2444.09 rows=1 width=1390) (actual time=700.651..700.690 rows=10 loops=1)
        ->  HashAggregate  (cost=2435.63..2435.64 rows=1 width=4) (actual time=700.630..700.630 rows=10 loops=1)
              Group Key: products_1.id
              ->  Limit  (cost=2435.62..2435.62 rows=1 width=72) (actual time=700.619..700.619 rows=10 loops=1)
                    ->  Sort  (cost=2434.00..2435.62 rows=646 width=72) (actual time=697.304..699.868 rows=30010 loops=1)
                          Sort Key: products_1.score, products_1.title
                          Sort Method: quicksort  Memory: 7396kB
                          ->  Bitmap Heap Scan on products products_1  (cost=17.01..2403.85 rows=646 width=72) (actual time=10.796..32.258 rows=41666 loops=1)
                                Recheck Cond: (category_ids @> '{248688}'::integer[])
                                Heap Blocks: exact=6471
                                ->  Bitmap Index Scan on idx_products_category_ids_gin  (cost=0.00..16.85 rows=646 width=0) (actual time=9.234..9.234 rows=41666 loops=1)
                                      Index Cond: (category_ids @> '{248688}'::integer[])
        ->  Index Scan using products_pkey on products  (cost=0.42..8.45 rows=1 width=1390) (actual time=0.004..0.004 rows=1 loops=10)
              Index Cond: (id = products_1.id)
Planning time: 1.015 ms
Execution time: 700.918 ms

다양한 오프셋과 제품 수로 재생하면 PostgreSQL에서 추가 B-tree 인덱스를 사용할 수 없습니다.

그래서 고전적인 길을 가고 접합 테이블을 만들었습니다 .

CREATE TABLE prodcats AS SELECT id AS product_id, unnest(category_ids) AS category_id FROM products;
CREATE INDEX idx_prodcats_cat_prod_id ON prodcats (category_id, product_id);

SELECT p.* FROM products p JOIN prodcats c ON (p.id=c.product_id)
WHERE c.category_id=248688
ORDER BY p.score DESC, p.title LIMIT 10 OFFSET 30000;

Limit  (cost=122480.06..122480.09 rows=10 width=1390) (actual time=1290.360..1290.362 rows=10 loops=1)
  ->  Sort  (cost=122405.06..122509.00 rows=41574 width=1390) (actual time=1264.250..1289.575 rows=30010 loops=1)
        Sort Key: p.score, p.title
        Sort Method: external merge  Disk: 29656kB
        ->  Merge Join  (cost=50.46..94061.13 rows=41574 width=1390) (actual time=117.746..182.048 rows=41666 loops=1)
              Merge Cond: (p.id = c.product_id)
              ->  Index Scan using products_pkey on products p  (cost=0.42..90738.43 rows=646067 width=1390) (actual time=0.034..116.313 rows=210283 loops=1)
              ->  Index Only Scan using idx_prodcats_cat_prod_id on prodcats c  (cost=0.43..1187.98 rows=41574 width=4) (actual time=0.022..7.137 rows=41666 loops=1)
                    Index Cond: (category_id = 248688)
                    Heap Fetches: 0
Planning time: 0.873 ms
Execution time: 1294.826 ms

여전히 B- 트리 인덱스를 사용하지 않아 결과 집합이 맞지 work_mem않아 결과가 좋지 않습니다.

그러나 상황에 따라 많은 제품작은 오프셋을 가진 PostgreSQL은 이제 B- 트리 인덱스를 사용하기로 결정합니다.

SELECT p.* FROM products p JOIN prodcats c ON (p.id=c.product_id)
WHERE c.category_id=248688
ORDER BY p.score DESC, p.title LIMIT 10 OFFSET 300;

Limit  (cost=3986.65..4119.51 rows=10 width=1390) (actual time=264.176..264.574 rows=10 loops=1)
  ->  Nested Loop  (cost=0.98..552334.77 rows=41574 width=1390) (actual time=250.378..264.558 rows=310 loops=1)
        ->  Index Scan using idx_test7 on products p  (cost=0.55..194665.62 rows=646067 width=1390) (actual time=0.030..83.026 rows=108037 loops=1)
        ->  Index Only Scan using idx_prodcats_cat_prod_id on prodcats c  (cost=0.43..0.54 rows=1 width=4) (actual time=0.001..0.001 rows=0 loops=108037)
              Index Cond: ((category_id = 248688) AND (product_id = p.id))
              Heap Fetches: 0
Planning time: 0.585 ms
Execution time: 264.664 ms

여기서 B- 트리 인덱스는 직접적인 결과를 생성하지 않으므로 순차 검색을위한 가이드로만 사용되므로 실제로 매우 논리적입니다.

GIN 쿼리와 비교해 봅시다 :

SELECT * FROM products WHERE id in (
  SELECT id FROM products WHERE category_ids @> ARRAY[248688]
  ORDER BY score DESC, title LIMIT 10 OFFSET 300
) ORDER BY score DESC, title;

Sort  (cost=2519.53..2519.55 rows=10 width=1390) (actual time=143.809..143.809 rows=10 loops=1)
  Sort Key: products.score, products.title
  Sort Method: quicksort  Memory: 35kB
  ->  Nested Loop  (cost=2435.14..2519.36 rows=10 width=1390) (actual time=143.693..143.736 rows=10 loops=1)
        ->  HashAggregate  (cost=2434.71..2434.81 rows=10 width=4) (actual time=143.678..143.680 rows=10 loops=1)
              Group Key: products_1.id
              ->  Limit  (cost=2434.56..2434.59 rows=10 width=72) (actual time=143.668..143.670 rows=10 loops=1)
                    ->  Sort  (cost=2433.81..2435.43 rows=646 width=72) (actual time=143.642..143.653 rows=310 loops=1)
                          Sort Key: products_1.score, products_1.title
                          Sort Method: top-N heapsort  Memory: 68kB
                          ->  Bitmap Heap Scan on products products_1  (cost=17.01..2403.85 rows=646 width=72) (actual time=11.625..31.868 rows=41666 loops=1)
                                Recheck Cond: (category_ids @> '{248688}'::integer[])
                                Heap Blocks: exact=6471
                                ->  Bitmap Index Scan on idx_products_category_ids_gin  (cost=0.00..16.85 rows=646 width=0) (actual time=9.916..9.916 rows=41666 loops=1)
                                      Index Cond: (category_ids @> '{248688}'::integer[])
        ->  Index Scan using products_pkey on products  (cost=0.42..8.45 rows=1 width=1390) (actual time=0.004..0.004 rows=1 loops=10)
              Index Cond: (id = products_1.id)
Planning time: 0.630 ms
Execution time: 143.921 ms

GIN의 결과가 훨씬 좋습니다. 상황에 따라 정션 테이블 접근 방식이 더 나아진 것은 아닙니다. 다양한 제품 조합과 오프셋을 확인했습니다 .

실 지수의 힘

PostgreSQL이 정렬을 위해 인덱스를 완전히 활용 하려면 매개 변수 WHERE뿐만 아니라 모든 쿼리 매개 변수 ORDER BY가 단일 B- 트리 인덱스에 있어야합니다. 이를 위해 정렬 필드를 제품에서 정션 테이블로 복사했습니다.

CREATE TABLE prodcats AS SELECT id AS product_id, unnest(category_ids) AS category_id, score, title FROM products;
CREATE INDEX idx_prodcats_1 ON prodcats (category_id, score DESC, title, product_id);

SELECT * FROM products WHERE id in (SELECT product_id FROM prodcats WHERE category_id=248688 ORDER BY score DESC, title LIMIT 10 OFFSET 30000) ORDER BY score DESC, title;

Sort  (cost=2149.65..2149.67 rows=10 width=1390) (actual time=7.011..7.011 rows=10 loops=1)
  Sort Key: products.score, products.title
  Sort Method: quicksort  Memory: 35kB
  ->  Nested Loop  (cost=2065.26..2149.48 rows=10 width=1390) (actual time=6.916..6.950 rows=10 loops=1)
        ->  HashAggregate  (cost=2064.83..2064.93 rows=10 width=4) (actual time=6.902..6.904 rows=10 loops=1)
              Group Key: prodcats.product_id
              ->  Limit  (cost=2064.02..2064.71 rows=10 width=74) (actual time=6.893..6.895 rows=10 loops=1)
                    ->  Index Only Scan using idx_prodcats_1 on prodcats  (cost=0.56..2860.10 rows=41574 width=74) (actual time=0.010..6.173 rows=30010 loops=1)
                          Index Cond: (category_id = 248688)
                          Heap Fetches: 0
        ->  Index Scan using products_pkey on products  (cost=0.42..8.45 rows=1 width=1390) (actual time=0.003..0.003 rows=1 loops=10)
              Index Cond: (id = prodcats.product_id)
Planning time: 0.318 ms
Execution time: 7.066 ms

그리고 이것은 선택된 카테고리에 많은 수의 제품과 큰 오프셋이있는 최악의 시나리오입니다. 오프셋 = 300 일 때 실행 시간은 0.5ms에 불과합니다.

불행히도 이러한 정션 테이블을 유지 보수 하려면 추가 노력이 필요합니다. 인덱싱 된 구체화 된 뷰를 통해 수행 할 수 있지만, 데이터를 거의 업데이트하지 않는 경우에만 유용합니다. 구체화 된 뷰를 새로 고치는 것이 상당히 큰 작업입니다.

그래서 work_mem메모리 풋 프린트 쿼리 가 증가 하고 감소 하면서 지금까지 GIN 인덱스를 유지하고 있습니다.


postgresql.conf 에서 일반 설정을 변경 하기 위해 다시 시작할 필요 는 없습니다 . 새로 고침 으로 충분합니다. 그리고 다중 사용자 환경에서 너무 높게 설정 하지 않도록 경고 합니다 (너무 낮지 않음). 당신이 경우 몇 가지 더 필요한 쿼리를 , 세션에만 함께 그것을 높게 설정 하거나 그냥 거래 - . 참조 : dba.stackexchange.com/a/48633/3684work_memwork_memwork_memSETSET LOCAL
Erwin Brandstetter

좋은 답변입니다. 특히 디스크-> 메모리 내 정렬 작업, 큰 승리를위한 빠른 변경으로 많은 도움이되었습니다!
Ricardo Villamil

4

다음은 성능 향상에 도움이되는 몇 가지 빠른 팁입니다. 가장 쉬운 팁부터 시작하겠습니다.이 팁은 사용자가 거의 어려움을 겪지 않으며 처음부터 더 어려운 팁으로 넘어갑니다.

1. work_mem

따라서 귀하의 Explain Plan에보고 된 정렬 Sort Method: external merge Disk: 5696kB이 6MB 미만을 소비하지만 디스크에 유출되고 있음을 알 수 있습니다. 정렬이 메모리에 들어갈 수있을만큼 파일 의 work_mem설정 을 늘려야합니다 postgresql.conf.

편집 : 또한 추가 검사에서 인덱스를 사용 catgory_ids하여 기준에 맞는 것을 확인한 후 비트 맵 인덱스 스캔이 "손실"되고 강제로 관련 힙 페이지 내에서 행을 읽을 때 조건을 다시 확인해야합니다. . 내가 제공 한 것보다 더 나은 설명은 postgresql.org 에서이 게시물참조하십시오 . : P 요점은 당신 work_mem이 너무 낮다는 것입니다. 서버의 기본 설정을 조정하지 않으면 제대로 작동하지 않습니다.

이 수정은 본질적으로 할 시간이 없습니다. 로 한 번 변경 postgresql.conf하면 나갔습니다! 추가 정보는이 성능 조정 페이지 를 참조하십시오 .

2. 스키마 변경

따라서 스키마 디자인에서 category_ids정수 배열 을 비정규 화하기 로 결정한 후 GIN 또는 GIST 인덱스를 사용하여 빠르게 액세스 할 수 있습니다. 내 경험상, GIN 인덱스를 선택하는 것이 GIST보다 읽기에 더 빠르므로이 경우 올바른 선택을해야합니다. 그러나 GIN은 정렬되지 않은 인덱스입니다. 더 술어가 확인하기 쉬운 키 - 값,하지만 같은 작업처럼 생각 WHERE >, WHERE <또는 ORDER BY인덱스에 의해 촉진되지 않습니다.

적절한 접근 방식은 데이터베이스에서 다 대다 관계를 지정하는 데 사용되는 브리지 테이블 / 접합 테이블 을 사용하여 설계를 정규화하는 것 입니다.

이 경우 많은 카테고리와 해당 정수 세트가 category_id있으며 많은 제품과 해당 정수 가 있습니다 product_id. category_ids 의 정수 배열 인 제품 테이블의 열 대신 스키마에서이 배열 열을 제거하고 다음과 같이 테이블을 작성하십시오.

CREATE TABLE join_products_categories (product_id int, category_id int);

그런 다음 브리지 테이블의 두 열에서 B- 트리 인덱스를 생성 할 수 있습니다.

CREATE INDEX idx_products_in_join_table ON join_products_categories (product_id);
CREATE INDEX idx_products_in_join_table ON join_products_categories (category_id);

저의 겸손한 의견이지만 이러한 변화로 인해 큰 변화가 생길 수 있습니다. work_mem최소한 그 변화를 먼저 시도하십시오 .

행운을 빕니다!

편집하다:

정렬을 돕기 위해 추가 색인 작성

따라서 시간이 지남에 따라 제품군이 확장되면 특정 쿼리는 많은 결과 (수만, 수만?)를 반환 할 수 있지만 여전히 전체 제품군의 작은 하위 집합 일 수 있습니다. 이러한 경우 메모리에서 수행하면 정렬 비용이 많이 들지만 정렬을 돕기 위해 적절하게 설계된 색인을 사용할 수 있습니다.

인덱스 및 ORDER BY를 설명하는 공식 PostgreSQL 설명서를 참조하십시오 .

ORDER BYreqirements와 일치하는 색인을 작성하는 경우

CREATE INDEX idx_product_sort ON products (score DESC, title);

Postgres는 색인을 사용하거나 명시적인 정렬을 수행하는 것이 더 비용 효율적인지 여부를 최적화하고 결정합니다. Postgres가 색인을 사용할 것이라는 보장없습니다 . 성능을 최적화하고 인덱스 사용 또는 명시 적 정렬 중에서 선택합니다. 이 색인을 작성하는 경우 색인을 작성하여 작성을 정당화하기에 충분히 사용되고 있는지 확인하고 대부분의 정렬이 명시 적으로 수행되는 경우 삭제하십시오.

그럼에도 불구하고이 시점에서 귀하의 '벅을위한 가장 큰 강타'개선이 더 많이 사용될 것 work_mem같지만 색인이 정렬을 지원할 수있는 경우가 있습니다.


또한 GIN을 피하기 위해 접합 테이블을 사용하는 것에 대해 생각하고있었습니다. 그러나 정렬에 도움이 될 방법을 지정하지 않았습니다. 나는 그것이 도움이되지 않을 것이라고 생각합니다. 나는 GIN 쿼리를 통해 수집 한 일련의 제품 ID로 제품 테이블에 가입하려고 시도했지만 제공하는 조인과 매우 유사하다고 생각하며 점수 및 제목에 b-tree 인덱스를 사용할 수 없습니다. 어쩌면 나는 잘못된 색인을 만들었습니다. 좀 더 자세히 설명해 주시겠습니까?
Yaroslav Stavnichiy 2016 년

사과, 아마도 충분히 명확하게 설명하지 않았을 것입니다. work_mem구성 변경은 '디스크 정렬'문제 및 재확인 조건 문제에 대한 수정으로 고안되었습니다. 제품 수가 증가함에 따라 정렬 할 추가 색인이 필요할 수 있습니다. 명확성을 위해 위의 편집 내용을 참조하십시오.
Chris
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.