복붙노트

[SQL] PostgreSQL의에서 카디널리티 추정 오차를 표시하는 쿼리 샘플

SQL

PostgreSQL의에서 카디널리티 추정 오차를 표시하는 쿼리 샘플

나는 PostgreSQL9.3를 사용하여 프로젝트를 진행하고있다. 나는 선택도 추정 오류가 PostgreSQL8.3를 사용하여 워크로드 TPC-H 쿼리 실행 시간이 다 배 증가시킬 수있는 방법을 보여 쿼리 아래를 사용하고 있었다.

select 
    n_name, 
    sum(l_extendedprice * (1 - l_discount)) as revenue 
from 
    customer, 
    orders, 
    lineitem, 
    supplier, 
    nation,
    region 
where 
    c_custkey = o_custkey 
    and l_orderkey = o_orderkey 
    and l_suppkey = s_suppkey   
    and c_nationkey = s_nationkey 
    and s_nationkey = n_nationkey 
    and n_regionkey = r_regionkey 
    and (r_name='ASIA' or r_name='AFRICA') 
    and o_orderdate >= date '1994-01-01' 
    and o_orderdate < date '1994-01-01' + interval '1 year' 
    and l_shipdate <= l_receiptdate 
    and l_commitdate <= l_shipdate + integer '90' 
    and l_extendedprice <= 20000 
    and c_name like '%r#00%' 
    and c_acctbal <=2400 
group by 
    n_name 
order by    
    revenue desc

문제는 PostgreSQL8.3가 LINEITEM 및 고객에 대한 선택도 추정은 큰 차이로 잘못 된 이후 NestedLoop의 많은 조인을 포함하는 계획을 선택했다이었다. 나는이 LIKE 패턴 매칭 majorly 때문이었다 생각합니다. 그러나 최적의 계획은 해시 조인 사용하고 있어야합니다.

최근에 나는 내 프로젝트에 대한 PostgreSQL9.3으로 업그레이드하고 위의 쿼리가 더 이상 나쁜 계획을주는 것을 관찰합니다. 나는 지금까지 어떤 성공 TPC-H 기가 바이트의 데이터에 큰 카디널리티 추정 오차가있는 쿼리를 찾기 위해 노력하고 일정 시간을 보냈다. 어떤 PostgreSQL의 괴짜 PostgreSQL9.3에서 카디널리티 추정 오차를 보여 TPC-H 벤치 마크에서 선반 쿼리 또는 쿼리 떨어져 몇 가지를 알고 있습니까

해결법

  1. ==============================

    1.이 @Twelfth에 의해 코멘트뿐만 아니라 질문 자체에 대답하는 것입니다.

    이 @Twelfth에 의해 코멘트뿐만 아니라 질문 자체에 대답하는 것입니다.

    설명서의이 장에서 세 따옴표 : "명시와 플래너 제어 절 가입하세요"

    ...

    ...

    굵게 강조 광산. 반대로, 당신은 당신의 테스트 목적을 위해 나쁜 쿼리 계획에 대한 쿼리 계획을 직접 같은 학대 할 수 있습니다. 전체 매뉴얼 페이지를 참조하십시오. 그것은 수단이 있어야한다.

    또한, (세션 만에 최고) 대체 방법을 하나씩 해제하여 중첩 된 루프를 강제 할 수 있습니다. 처럼:

    SET enable_hashjoin = off;
    

    기타. 확인하고 매개 변수를 설정하는 방법에 대한 :

    한 가지 확실한 방법은 사용하지 않도록 자동 진공으로하고 테이블에서 행을 추가 / 제거 할 것입니다. 그런 다음 쿼리 계획은 오래된 통계 노력하고 있습니다. 다른 명령이 아니라 통계를 갱신합니다.

    통계는 카탈로그 테이블 pg_class와 pg_statistics에 저장됩니다.

    SELECT * FROM pg_class WHERE oid = 'mytable'::regclass;
    SELECT * FROM pg_statistic WHERE starelid = 'mytable'::regclass;
    

    이것은 또 다른 옵션으로 날 리드. 이러한 두 테이블의 항목을 위조 할 수있다. 수퍼 유저 권한이 필요합니다. 당신은 신인,하지만 일반 대중에 대한 경고로 나를 공격하지 않습니다 당신이 카탈로그 테이블에서 뭔가를 깰 경우 데이터베이스 (클러스터) 아랫배 올라갈 수 있습니다. 당신은 경고되었다.

  2. from https://stackoverflow.com/questions/25002263/sample-query-to-show-cardinality-estimation-error-in-postgresql by cc-by-sa and MIT license