post gresql 색인 을 통 해 조회 속도 최적화 작업

데이터 양 이 비교적 많 을 때 조회 효율 을 높이 는 것 은 고려 해 야 할 일이 다.백만 단계 의 표 가 최적화 되 지 않 으 면 가장 간단 한 조회 문 구 를 실행 하 는 것 도 느 려 서 받 아들 이기 어렵다.물론'최적화'자 체 는 비교적 복잡 한 프로젝트 로 디자인 표,필드 부터 조회 문 구 를 작성 하 는 방법 까지 모두 많은 관심 을 가진다.여 기 는 색인 방식 만 고려 하고 가장 일반적인 색인 이다.
아래 작업 에 대응 하 는 데이터베이스 테이블 w008execrise_info(8000 데이터 양),w008wf02_info(4000 데이터 양)
1 태 스 크 시트 데이터

SELECT
 w.*
FROM
 w008_wf02_info w 
WHERE
 w.is_removed =0
 AND w.wfno = 'WF02' 
 AND EXISTS (
SELECT
 1 
FROM
 w008_execrise_info info
 JOIN w008_privilege_allocation P ON (
 info.subjecttyp = P.subjecttyp 
 AND info.gradetyp = P.gradetyp 
 AND P.loginname = w.create_by 
 AND P.verifyusers ='yixi_li'
 AND P.wftype = 20 
 ) 
WHERE
 info.is_removed =0 
 AND info.wfid = w.wfid 
 ) 
 
ORDER BY
 create_date DESC
실행 결과:3 초 정도 걸 립 니 다.

참고 로 여기 서 w.*를 대응 하 는 필드 로 바 꾸 는 것 도 조회 속 도 를 약간 높 일 수 있 습 니 다.
2 색인 추가:
색인 은 조회 속 도 를 높 일 수 있 지만 색인 을 넣 으 면 반드시 조회 속 도 를 빠르게 하 는 것 은 아니 며,때로는 역 효 과 를 낼 수도 있다.
일반적으로 색인 은 where 뒤의 조회 필드,특히 관련 필드 에 추 가 됩 니 다.여기 w008execrise_info 표 데이터 양 이 가장 많 습 니 다.이 표 에 대해 잠시 처리 합 니 다.w008_execrise_info 표 는 네 개의 필드 와 관련된다:subjecttyp,gradetyp,wfid 와 isremoved。
그 중 isremoved 는 고려 하지 않 고 subjecttyp 와 gradetyp 은 사전 표 의 데이터(데이터 내용 이 적 고 10,20,30,40 과 유사)를 저장 하고 wfid 는 디지털 형식의 문자열 을 저장 합 니 다.
하나의 색인 이 가 져 오 는 효 과 는 이러한 조건 에 달 려 있다.일반적으로 색인 을 추가 하 는 필드 의 값 은'유일 성'이 뚜렷 할 수록 좋다.여기 서 subjecttyp 와 gradetyp 은 대량의 중복 값 을 포함 하고 색인 효 과 는'뚜렷 하지 않다'고 할 수 있 으 며,wfid 는'메 인 키'와 같 아서 상대 적 으로 효과 가 훨씬 좋다.
2.1 subjecttyp 와 gradetyp 에 색인 추가
CREATE INDEX w008_execrise_info_gradetyp_index ON w008_execrise_info (gradetyp);
CREATE INDEX w008_execrise_info_subjecttyp_index ON w008_execrise_info (subjecttyp);
추가 후 실행 시간 은 약 2 초 입 니 다.조금 빨 라 졌 습 니 다.

2.2 wfid 에 색인 추가
CREATE INDEX w008_execrise_info_wfid_index ON w008_execrise_info (wfid);
다시 실행,0.2 초 정도,많이 빨 라 졌 습 니 다.

한 마디 만 더 하면 색인 이 작용 하지 않 는 경우 가 많 습 니 다.예 를 들 어 like 뒤의 필드,그리고 조건 문 or 와 관련 된 필드 가 있 습 니 다.이런 상황 은 조회 전략 을 고려 해 야 합 니 다.
3.현재 표 의 색인 내용 보기;
select * from pg_indexes where tablename='w008_execrise_info';

select * from pg_statio_all_indexes where relname='w008_execrise_info';

4 색인 삭제
DROP INDEX indexName;
5 인덱스 초기 화
자주 바 뀌 는 표 에 대해 서 는 시간 이 지나 면 조회 효율 이 느 려 지 는 것 을 발견 하면 색인 리 셋 을 고려 할 수 있다.
표 의 내용 이 자주 수정 되면'색인 조각'과 유사 한 것 이 많이 생 겨 색인 자 체 를 조회 하 는 시간 이 길 어 지기 때문이다.

 REINDEX INDEX index_name;//      
 REINDEX TABLE table_name;//        
 REINDEX DATABASE db_name;//           
추가:PostgreSql 조회 최적화 실행 계획 에 따라 SQL 최적화
1.실행 계획 경로 선택
post gresql 조회 계획 과정 에서 조회 요청 의 서로 다른 실행 방안 은 서로 다른 경 로 를 구축 하여 표현 하 는 것 입 니 다.조건 에 부합 되 는 경 로 를 많이 생 성 한 후에 그 중에서 대가 가 가장 적은 경로(원가 연산 기반)를 선택 하여 이 를 하나의 계획 으로 전환 시 켜 집행 기 에 전달 하고 기획 기의 핵심 작업 은 여러 가지 경 로 를 생 성 하 는 것 입 니 다.그 중에서 가장 좋 은 것 을 찾 아 라.
1.1 대가 평가
경로 의 우열 을 평가 하 는 근 거 는 시스템 표 pgstatistic 에서 통계 정 보 를 평가 한 서로 다른 경로 의 대가(cost),PostgreSQL 은 계획 원 가 를 평가 하 는 방식:통계 정 보 를 바탕 으로 계획 중의 각 노드 의 원 가 를 평가 합 니 다.PostgreSQL 은 각 표를 분석 하여 통계 정보 샘플 을 얻 습 니 다.statistic 와 pgclass 안.
1.2 대 가 를 추산 하 는 매개 변수 postgresql.conf

# - Planner Cost Constants -
 
#seq_page_cost = 1.0  # measured on an arbitrary scale               
 
#random_page_cost = 4.0  # same scale as above                
 
#cpu_tuple_cost = 0.01  # same scale as above cpu        
 
#cpu_index_tuple_cost = 0.005 # same scale as above cpu          
 
#cpu_operator_cost = 0.0025 # same scale as above cpu                
 
#parallel_tuple_cost = 0.1 # same scale as above          ,         ,         。
 
#parallel_setup_cost = 1000.0 # same scale as above
 
#min_parallel_relation_size = 8MB
 
#effective_cache_size = 4GB                         
쇼 all 로 도 볼 수 있어 요.
1.3 경로 선택
--표 정보 보기

highgo=# \d t_jcxxgl_tjaj
 
  Table "db_jcxx.t_jcxxgl_tjaj"
 
 Column |  Type  | Modifiers --------------+--------------------------------+-----------
 
 c_bh | character(32)   | not null
 
 c_xzdm | character varying(300)  |
 
 c_jgid | character(32)   |
 
 c_ajbm | character(22)   |
 
...
 
Indexes:
 
 "t_jcxxgl_tjaj_pkey" PRIMARY KEY, btree (c_bh)
 
 "idx_ttjaj_cah" btree (c_ah)
 
 "idx_ttjaj_dslrq" btree (d_slrq)
우선 통계 정보 업데이트 진공 분석 tjcxxgl_tjaj,많은 경우 통계 정보의 부정 확 함 으로 인해 비정상적인 실행 계획 인 실행 계획 을 초래 할 수 있 습 니 다.
--실행 계획,전 표 스 캔

highgo=# explain (analyze,verbose,costs,buffers,timing)select c_bh,c_xzdm,c_jgid,c_ajbm from t_jcxxgl_tjaj where d_slrq >='2018-03-18';
 
       QUERY PLAN      ------------------------------------------------------------------------------------------------------------
 
 Seq Scan on db_jcxx.t_jcxxgl_tjaj (cost=0.00..9.76 rows=3 width=96) (actual time=1.031..1.055 rows=3 loops
 
=1)
 
 Output: c_bh, c_xzdm, c_jgid, c_ajbm
 
 Filter: (t_jcxxgl_tjaj.d_slrq >= '2018-03-18'::date)
 
 Rows Removed by Filter: 138
 
 Buffers: shared hit=8
 
 Planning time: 6.579 ms
 
 Execution time: 1.163 ms
 
(7 rows)
위 와 같이 dslrq 는 색인 이 있 지만 실행 계획 에 색인 이 없습니다.왜 일 까요?우 리 는 계속 아래 를 내 려 다 보 았 다.
--계획 을 실행 하고,전체 테이블 스 캔 을 종료

highgo=# set session enable_seqscan = off;
 
SET
 
highgo=# explain (analyze,verbose,costs,buffers,timing)select c_bh,c_xzdm,c_jgid,c_ajbm from t_jcxxgl_tjaj where d_slrq >='2018-03-18';
 
        QUERY PLAN        ------------------------------------------------------------------------------------------------------------
 
 Index Scan using idx_ttjaj_dslrq on db_jcxx.t_jcxxgl_tjaj (cost=0.14..13.90 rows=3 width=96) (actual time=0.012..0.026 rows=3 loops=1)
 
 Output: c_bh, c_xzdm, c_jgid, c_ajbm
 
 Index Cond: (t_jcxxgl_tjaj.d_slrq >= '2018-03-18'::date)
 
 Buffers: shared hit=4
 
 Planning time: 0.309 ms
 
 Execution time: 0.063 ms
 
(6 rows)
d_slrq 위 에 btree 색인 이 있 지만 실행 계획 을 보고 색인 을 찾 지 않 았 습 니 다.왜 일 까요?
대가 계산:
하나의 경로 에 대한 추산 은 세 부분 으로 구성 되 어 있 습 니 다.시작 대가(startup cost),총 대가(totalcost),실행 결과 의 정렬 방식(pathkeys)입 니 다.
대가 추산 공식:
총 대가=시작 대가+I/O 대가+CPU 대가(cost=S+P+W*T)
P:실행 할 때 접근 할 페이지 수,반응 디스크 의 I/O 횟수
T:실행 할 때 방문 할 원 그룹 수 를 표시 합 니 다.cpu 비용 을 반영 합 니 다.
W:디스크 I/O 대가 와 CPU 지출 을 나타 내 는 가중치 인자
통계 정보:
통계 정보의 일부분 은 표 와 색인 중 항목 의 총수,그리고 표 와 색인 이 차지 하 는 디스크 블록 이다.이 정 보 는 pg 에 저 장 됩 니 다.class 표 의 reltuples 와 relpages 열 에 있 습 니 다.우 리 는 이렇게 관련 정 보 를 조회 할 수 있다.
--통계 정보 보기

highgo=# select relpages,reltuples from pg_class where relname ='t_jcxxgl_tjaj';
 
 relpages | reltuples ----------+-----------
 
 8 | 141
 
(1 row)
total_cost = 1(seq_page_cost)*8(디스크 총 페이지 수)+0.01(cputuple_cost)*141(표 의 총 기록 수)+0.0025(cpuoperation_cost)*141(표 의 총 기록 수)=9.7625
색인 을 볼 수 있 는 cost=13.90 은 전체 표 스 캔 cost=9.76 보다 크다.그래서 위 에서 전체 표 스 캔 을 닫 지 않 았 을 때 원가 대가 에 따라 계획 한 전체 표 스 캔 을 실행 합 니 다.표 가 비교적 작은 상황 에서 전체 표 스 캔 은 색인 스 캔 보다 더욱 효과 적 입 니 다.index scan 은 적어도 두 번 의 I/O 가 발생 합 니 다.한 번 은 색인 블록 을 읽 고 한 번 은 데이터 블록 을 읽 습 니 다.
2.SQL 최적화 인 스 턴 스
2.1 느 린 SQL:

select c_ajbh, c_ah, c_cbfy, c_cbrxm, d_larq, d_jarq, n_dbjg, c_yqly from db_zxzhld.t_zhld_db dbxx join db_zxzhld.t_zhld_ajdbxx dbaj on dbxx.c_bh = dbaj.c_dbbh where dbxx.n_valid=1 and dbxx.n_state in (1,2,3) and dbxx.c_dbztbh='1003' and dbaj.c_zblx='1003' and dbaj.c_dbfy='0' and dbaj.c_gy = '2550' and c_ajbh in (select distinct c_ajbh from db_zxzhld.t_zhld_zbajxx where n_dbzt = 1 and c_zblx = '1003' and c_gy = '2550' ) order by d_larq asc, c_ajbh asc limit 15 offset 0;
느 린 sql 소모 시간:7s
먼저 이 sql 이 무엇 을 하 는 지,먼저 dbxx 와 dbaj 의 join 연결 을 한 다음 dbaj.cajbh 는 zbaj 표 에 포함 시 키 려 면 정렬 을 하고 15 개의 기록 을 취 했 습 니 다.대략 이 렇 습 니 다.
Sql 의 단점 은 검색 필드 가 그 표 에서 지 어 졌 는 지 모 르 는 것 입 니 다.표 별명,필드 를 추가 하 는 것 을 권장 합 니 다.
이 sql 표 의 데이터 양 보기:

  t_zhld_db :1311
  t_zhld_ajdbxx :341296
 t_zhld_zbajxx :1027619 
실행 계획:

 Limit (cost=36328.67..36328.68 rows=1 width=107) (actual time=88957.677..88957.729 rows=15 loops=1)
 
 -> Sort (cost=36328.67..36328.68 rows=1 width=107) (actual time=88957.653..88957.672 rows=15 loops=1)
 
  Sort Key: dbaj.d_larq, dbaj.c_ajbh
 
  Sort Method: top-N heapsort Memory: 27kB
 
  -> Nested Loop Semi Join (cost=17099.76..36328.66 rows=1 width=107) (actual time=277.794..88932.662 rows=8605 loops=1)
 
  Join Filter: ((dbaj.c_ajbh)::text = (t_zhld_zbajxx.c_ajbh)::text)
 
  Rows Removed by Join Filter: 37018710
 
  -> Nested Loop (cost=0.00..19200.59 rows=1 width=107) (actual time=199.141..601.845 rows=8605 loops=1)
 
   Join Filter: (dbxx.c_bh = dbaj.c_dbbh)
 
   Rows Removed by Join Filter: 111865
 
   -> Seq Scan on t_zhld_ajdbxx dbaj (cost=0.00..19117.70 rows=219 width=140) (actual time=198.871..266.182 rows=8605 loops=1)
 
    Filter: ((n_valid = 1) AND ((c_zblx)::text = '1003'::text) AND ((c_dbfy)::text = '0'::text) AND ((c_gy)::text = '2550'::text))
 
    Rows Removed by Filter: 332691
 
   -> Materialize (cost=0.00..66.48 rows=5 width=33) (actual time=0.001..0.017 rows=14 loops=8605)
 
    -> Seq Scan on t_zhld_db dbxx (cost=0.00..66.45 rows=5 width=33) (actual time=0.044..0.722 rows=14 loops=1)
 
     Filter: ((n_valid = 1) AND ((c_dbztbh)::text = '1003'::text) AND (n_state = ANY ('{1,2,3}'::integer[])))
 
     Rows Removed by Filter: 1297
 
  -> Materialize (cost=17099.76..17117.46 rows=708 width=32) (actual time=0.006..4.890 rows=4303 loops=8605)
 
   -> HashAggregate (cost=17099.76..17106.84 rows=708 width=32) (actual time=44.011..54.924 rows=8605 loops=1)
 
    Group Key: t_zhld_zbajxx.c_ajbh
 
    -> Bitmap Heap Scan on t_zhld_zbajxx (cost=163.36..17097.99 rows=708 width=32) (actual time=5.218..30.278 rows=8605 loops=1)
 
     Recheck Cond: ((n_dbzt = 1) AND ((c_zblx)::text = '1003'::text))
 
     Filter: ((c_gy)::text = '2550'::text)
 
     Rows Removed by Filter: 21849
 
     Heap Blocks: exact=960
 
     -> Bitmap Index Scan on i_tzhldzbajxx_zblx_dbzt (cost=0.00..163.19 rows=5876 width=0) (actual time=5.011..5.011 rows=30458 loops=1)
 
     Index Cond: ((n_dbzt = 1) AND ((c_zblx)::text = '1003'::text))
 
 Planning time: 1.258 ms
 
 Execution time: 88958.029 ms
실행 계획 해독:
1:제2 7->21 줄,색인 을 통 해 itzhldzbajxx_zblx_dbzt 여과 표 tzhld_zbajxx 의 데이터,그리고 여과 조건 에 따라(cgy)::text='2550':text 여과 최종 8605 개의 데 이 터 를 되 돌려 줍 니 다.
2:제1 7->15 행,조건 에 따라 여과 tzhld_db 표 의 데 이 터 는 결국 14 개의 데 이 터 를 되 돌려 주 었 다.
3:제2 0->19 줄,표 tzhld_zbajxx group by 작업
4:제1 3->11 줄,전체 표 스 캔 tzhld_ajdbxx 는 결국 8605 개의 데 이 터 를 되 돌려 주 었 다.
5:08 번 째 줄,t 에 따라zhld_ajdbxx 가 돌아 온 8605 개의 결과 집합 을 구동 표 와 t 로 합 니 다.zhld_db 의 결과 집합(14 개)을 끼 워 넣 고 순환 합 니 다.tzhld_db 의 결과 집합 은 8605 회 순환 되 었 다.그리고 그 중의 111865 개의 기록 을 걸 러 내 면 최종 적 으로(8605*14-11865)=8605 를 얻 을 수 있 습 니 다.
6:07->05 줄,08 과 18 줄 로 돌아 온 결과 집에 따라 네 스 티 드 루프 세 미 조 인 트,18 줄 4303 조 결과 집 8605 회 순환,(4303*8605-37018710)=8605
7:04->02 줄,최종 8605 개의 기록 을 정렬 합 니 다.
8:01 번 째 줄,limit 최종 15 조 기록 획득
전체 실행 계획 중 가장 오래 걸 린 곳 은 05 행 Nested Loop Semi Join,actual time=277.794..88932.662,표 dbzxzhld.t_zhld_db dbxx 와 dbzxzhld.t_zhld_ajdbxx 는 모두 전체 표 스 캔 입 니 다.
2.2 구체 적 최적화 절차
색인 페이지 를 보 는데 색인 이 없습니다.c 생 성ajbh,c_dbbh 등 논리 외 키 의 색인

drop index if exists I_T_ZHLD_AJDBXX_AJBH;
 
create index I_T_ZHLD_AJDBXX_AJBH on T_ZHLD_AJDBXX (c_ajbh);
 
commit;
 
drop index if exists I_T_ZHLD_AJDBXX_DBBH;
 
create index I_T_ZHLD_AJDBXX_DBBH on T_ZHLD_AJDBXX (c_dbbh);
 
commit;
창설 dlarq,c_ajbh 정렬 인덱스:

drop index if exists I_T_ZHLD_AJDBXX_m6;create index I_T_ZHLD_AJDBXX_m6 on T_ZHLD_AJDBXX (c_zblx,c_dbfy,c_gy,d_larq asc,c_ajbh asc);
 
commit;
 
drop index if exists I_T_ZHLD_ZBAJXX_h3 ;
 
create index I_T_ZHLD_ZBAJXX_h3 on db_zxzhld.t_zhld_zbajxx (n_dbzt,c_zblx,c_gy,c_gy);
 
commit;
색인 을 만 든 후 실행 계획 이 바 뀌 었 습 니 다.원래 dbaj 표 와 dbxx 표 는 nestedloop 을 먼저 만 들 었 고 zbaj 와 dbaj 표 는 nestedloop join 을 먼저 만 들 었 습 니 다.전체적인 cost 도 36328.68 에서 12802.87 로 떨 어 졌 습 니 다.
계획 을 집행 하 다

Limit (cost=12802.87..12802.87 rows=1 width=107) (actual time=4263.598..4263.648 rows=15 loops=1)
 
 -> Sort (cost=12802.87..12802.87 rows=1 width=107) (actual time=4263.592..4263.609 rows=15 loops=1)
 
 Sort Key: dbaj.d_larq, dbaj.c_ajbh
 
 Sort Method: top-N heapsort Memory: 27kB
 
 -> Nested Loop (cost=2516.05..12802.86 rows=1 width=107) (actual time=74.240..4239.723 rows=8605 loops=1)
 
  Join Filter: (dbaj.c_dbbh = dbxx.c_bh)
 
  Rows Removed by Join Filter: 111865
 
  -> Nested Loop (cost=2516.05..12736.34 rows=1 width=140) (actual time=74.083..327.974 rows=8605 loops=1)
 
   -> HashAggregate (cost=2515.62..2522.76 rows=714 width=32) (actual time=74.025..90.185 rows=8605 loops=1)
 
    Group Key: ("ANY_subquery".c_ajbh)::text
 
    -> Subquery Scan on "ANY_subquery" (cost=2499.56..2513.84 rows=714 width=32) (actual time=28.782..59.823 rows=8605 loops=1)
 
    -> HashAggregate (cost=2499.56..2506.70 rows=714 width=32) (actual time=28.778..39.968 rows=8605 loops=1)
 
     Group Key: zbaj.c_ajbh
 
     -> Index Scan using i_t_zhld_zbajxx_h3 on t_zhld_zbajxx zbaj (cost=0.42..2497.77 rows=715 width=32) (actual time=0.062..15.104 rows=8605 loops=1)
 
      Index Cond: ((n_dbzt = 1) AND ((c_zblx)::text = '1003'::text) AND ((c_gy)::text = '2550'::text))
 
   -> Index Scan using i_t_zhld_ajdbxx_ajbh on t_zhld_ajdbxx dbaj (cost=0.42..14.29 rows=1 width=140) (actual time=0.015..0.021 rows=1 loops=8605)
 
    Index Cond: ((c_ajbh)::text = ("ANY_subquery".c_ajbh)::text)
 
    Filter: (((c_zblx)::text = '1003'::text) AND ((c_dbfy)::text = '0'::text) AND ((c_gy)::text = '2550'::text))
 
    Rows Removed by Filter: 1
 
  -> Seq Scan on t_zhld_db dbxx (cost=0.00..66.45 rows=5 width=33) (actual time=0.015..0.430 rows=14 loops=8605)
 
   Filter: ((n_valid = 1) AND ((c_dbztbh)::text = '1003'::text) AND (n_state = ANY ('{1,2,3}'::integer[])))
 
   Rows Removed by Filter: 1298
 
Planning time: 1.075 ms
 
Execution time: 4263.803 ms
실행 시간 은 4s 정도 로 여전히 수 요 를 만족 시 키 지 못 하고 I 를 사용 하지 않 았 습 니 다.T_ZHLD_AJDBXX_m6 이 색인.
2.3 등가 재 작성 SQL(1)
등가 개작:정렬 조건 을 db 에 추가 합 니 다.zxzhld.t_zhld_ajdbxx 먼저 정렬 시 킨 다음 tzhld_db 표 연결.
수정 후 sql:

Select dbaj.c_ajbh, dbaj.c_ah, dbaj.c_cbfy, dbaj.c_cbrxm, dbaj.d_larq, dbaj.d_jarq, dbaj.n_dbjg, dbaj.c_yqly from (select * from db_zxzhld.t_zhld_db where n_valid=1 and n_state in (1,2,3) and c_dbztbh='1003' )dbxx
 
 join (select * from db_zxzhld.t_zhld_ajdbxx where n_valid=1 and c_zblx='1003'
 
 and c_dbfy='0' and c_gy = '2550' and
 
c_ajbh in (select distinct c_ajbh from db_zxzhld.t_zhld_zbajxx where n_dbzt = 1 and c_zblx = '1003' and c_gy = '2550' ) order by d_larq asc, c_ajbh asc)dbajon dbxx.c_bh = dbaj.c_dbbh
 
 limit 15 offset 0
실행 계획 다시 보기:

Limit (cost=3223.92..3231.97 rows=1 width=107) (actual time=127.291..127.536 rows=15 loops=1)
 
 -> Nested Loop (cost=3223.92..3231.97 rows=1 width=107) (actual time=127.285..127.496 rows=15 loops=1)
 
 -> Sort (cost=3223.64..3223.65 rows=1 width=140) (actual time=127.210..127.225 rows=15 loops=1)
 
  Sort Key: t_zhld_ajdbxx.d_larq, t_zhld_ajdbxx.c_ajbh
 
  Sort Method: quicksort Memory: 2618kB
 
  -> Hash Semi Join (cost=2523.19..3223.63 rows=1 width=140) (actual time=55.913..107.265 rows=8605 loops=1)
 
   Hash Cond: ((t_zhld_ajdbxx.c_ajbh)::text = (t_zhld_zbajxx.c_ajbh)::text)
 
   -> Index Scan using i_t_zhld_ajdbxx_m6 on t_zhld_ajdbxx (cost=0.42..700.28 rows=219 width=140) (actual time=0.065..22.005 rows=8605 loops=1)
 
    Index Cond: (((c_zblx)::text = '1003'::text) AND ((c_dbfy)::text = '0'::text) AND ((c_gy)::text = '2550'::text))
 
   -> Hash (cost=2513.84..2513.84 rows=714 width=32) (actual time=55.802..55.802 rows=8605 loops=1)
 
    Buckets: 16384 (originally 1024) Batches: 1 (originally 1) Memory Usage: 675kB
 
    -> HashAggregate (cost=2499.56..2506.70 rows=714 width=32) (actual time=30.530..43.275 rows=8605 loops=1)
 
    Group Key: t_zhld_zbajxx.c_ajbh
 
    -> Index Scan using i_t_zhld_zbajxx_h3 on t_zhld_zbajxx (cost=0.42..2497.77 rows=715 width=32) (actual time=0.043..15.552 rows=8605 loops=1)
 
     Index Cond: ((n_dbzt = 1) AND ((c_zblx)::text = '1003'::text) AND ((c_gy)::text = '2550'::text))
 
 -> Index Scan using t_zhld_db_pkey on t_zhld_db (cost=0.28..8.30 rows=1 width=33) (actual time=0.009..0.011 rows=1 loops=15)
 
  Index Cond: (c_bh = t_zhld_ajdbxx.c_dbbh)
 
  Filter: (((c_dbztbh)::text = '1003'::text) AND (n_state = ANY ('{1,2,3}'::integer[])))
 
Planning time: 1.154 ms
 
Execution time: 127.734 ms
이번 에는 ajdbxx 와 zbajxx 표 가 hash semi join 을 만들어 nestedloop 을 제거 하고 cost 는 3231.97 로 떨 어 진 것 을 알 수 있다.그리고 i 를 사 용 했 습 니 다.t_zhld_ajdbxx_m6 서브 조회 에서 in 의 결과 집합 은 만 여 개의 데이터 가 있다.
exists 등 가 를 계속 사용 하여 in 을 고 쳐 서 더 좋 은 결과 가 있 을 수 있 는 지 시험 해 보 세 요.
2.4 등가 재 작성 SQL(2)
등가 변경:in 을 exists 로 바 꿉 니 다.

select c_ajbh, c_ah, c_cbfy, c_cbrxm, d_larq, d_jarq, n_dbjg, c_yqlyfrom (select c_bh from db_zxzhld.t_zhld_db where n_state in (1,2,3) and c_dbztbh='1003' )dbxx
 join (select c_ajbh, c_ah, c_cbfy, c_cbrxm, d_larq, d_jarq, n_dbjg, c_yqly,c_dbbh from db_zxzhld.t_zhld_ajdbxx ajdbxxwhere c_zblx='1003'
 and c_dbfy='0' and c_gy = '2550' and 
exists (select distinct c_ajbh from db_zxzhld.t_zhld_zbajxx zbajxx where ajdbxx.c_ajbh = zbajxx.c_ajbh and n_dbzt = 1 and c_zblx = '1003' and c_gy = '2550' ) order by d_larq asc, c_ajbh asc)dbajon dbxx.c_bh = dbaj.c_dbbh 
 limit 15 offset 0
실행 계획 다시 보기:

Limit (cost=1.12..2547.17 rows=1 width=107) (actual time=0.140..0.727 rows=15 loops=1)
 
 -> Nested Loop (cost=1.12..2547.17 rows=1 width=107) (actual time=0.136..0.689 rows=15 loops=1)
 
 -> Nested Loop Semi Join (cost=0.85..2538.84 rows=1 width=140) (actual time=0.115..0.493 rows=15 loops=1)
 
  -> Index Scan using i_t_zhld_ajdbxx_m6 on t_zhld_ajdbxx t2 (cost=0.42..700.28 rows=219 width=140) (actual time=0.076..0.127 rows=15 loops=1)
 
   Index Cond: (((c_zblx)::text = '1003'::text) AND ((c_dbfy)::text = '0'::text) AND ((c_gy)::text = '2550'::text))
 
  -> Index Scan using i_t_zhld_zbajxx_c_ajbh on t_zhld_zbajxx t3 (cost=0.42..8.40 rows=1 width=32) (actual time=0.019..0.019 rows=1 loops=15)
 
   Index Cond: ((c_ajbh)::text = (t2.c_ajbh)::text)
 
   Filter: (((c_zblx)::text = '1003'::text) AND ((c_gy)::text = '2550'::text) AND (n_dbzt = 1))
 
 -> Index Scan using t_zhld_db_pkey on t_zhld_db (cost=0.28..8.30 rows=1 width=33) (actual time=0.007..0.008 rows=1 loops=15)
 
  Index Cond: (c_bh = t2.c_dbbh)
 
  Filter: (((c_dbztbh)::text = '1003'::text) AND (n_state = ANY ('{1,2,3}'::integer[])))
 
Planning time: 1.268 ms
 
Execution time: 0.859 ms
exist 사용 효과 가 더 좋 음 을 알 수 있 습 니 다.최종 cost 2547.17
(1).tzhld_zbajxx 표 의 group by 조작:Sort Key:tzhld_ajdbxx.d_larq, t_zhld_ajdbxx.c_ajbh。(이 단 계 는 색인 에 있 는 정렬 을 사 용 했 기 때 문 입 니 다)
(2).그룹 작업 이 줄 었 습 니 다:Group Key:tzhld_zbajxx.c_ajbh。
제(2)왜 이 조회 가 t 를 없 앴 습 니까?zhld_zbajxx 표 의 group by 작업 은?
이 유 는 exists 가 distinct 의 기능 을 교체 하고 조건 을 만족 시 키 면 바로 돌아 오기 때문이다.그래서 exists 를 사용 할 때 하위 검색 은 distinct 를 직접 제거 할 수 있 습 니 다.
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.만약 잘못 이 있 거나 완전히 고려 하지 않 은 부분 이 있다 면 아낌없이 가르침 을 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기