2017-10-10 13 views
1

의 유니티를 검사 할 때 Postgres 테이블에 대한 필드의 유니티를 검사해야합니다. 단순화를 목적으로특정 상황 (큰 데이터 세트가 테이블에 저장되어 있음)이 주어지면 테이블 필드 postgres

의 나는 다음과 같은 테이블이 있다고 가정 해 봅시다 :

id | name 
-------------- 
1 | david 
2 | catrine 
3 | hmida 

을 내가 필드 이름의 유니시티를 확인하려면; 결과는 지금까지 나는 다음과 유사한 코드를 사용하여 관리되는 사실이 될 것이다 : 나는 큰 데이터 세트를 염두에

select name, count(*) 
from test 
group by name 
having count(*) > 1 

넣어, 그래서를 가져 오는 대신 RDBMS에 의해 처리 될이 선호 어댑터 (예 : psycopg2)에 의한 데이터. 다시 한번 나는 가능한 한 많이 최적화해야합니다. 어떤 괴상한 아이디어?

+0

작동하지 않는 코드가 있습니까? 질문은 무엇입니까? –

+0

쿼리가 1,000 만 행 데이터 집합에 2 분이 걸리면 훨씬 빠른 속도가 필요합니다. –

+0

은 DB 측에서 처리됩니다. psycopg2가 아닙니다. –

답변

1

이 아마 더 빨리,하지만 너무 신뢰할 수 없습니다 솔루션 것 :

지금
t=# create table t (i int); 
CREATE TABLE 
t=# insert into t select generate_series(1,9,1); 
INSERT 0 9 
t=# insert into t select generate_series(1,999999,1); 
INSERT 0 999999 
t=# insert into t select generate_series(1,9999999,1); 
INSERT 0 9999999 

조회 :

t=# select i,count(*) from t group by i having count(*) > 1 order by 2 desc,1 limit 1; 
i | count 
---+------- 
1 |  3 
(1 row) 

Time: 7538.476 ms 

지금 통계에서 확인 : 마지막으로

t=# analyze t; 
ANALYZE 
Time: 1079.465 ms 
    t=# with fr as (select most_common_vals::text::text[] from pg_stats where tablename = 't' and attname='i') 
    select count(1),i from t join fr on true where i::text = any(most_common_vals) group by i; 
    count | i 
    -------+-------- 
     2 | 94933 
     2 | 196651 
     2 | 242894 
     2 | 313829 
     2 | 501027 
     2 | 757714 
     2 | 778442 
     2 | 896602 
     2 | 929918 
     2 | 979650 
     2 | 999259 
    (11 rows) 

    Time: 3584.582 ms 

및 단지 확인 uniq가 가장 빈번한 값 중 하나만 존재한다면 :

통계가 테이블에 수집 한 후
t=# select count(1),i from t where i::text = (select (most_common_vals::text::text[])[1] from pg_stats where tablename = 't' and attname='i') group by i; 
count | i 
-------+------ 
    2 | 1540 
(1 row) 

Time: 1871.907 ms 

갱신

pg_stats 데이터 modifyed된다. 따라서 데이터 배포에 대한 통계를 새로 수집하지 않아도됩니다. 예를 들어 내 샘플에서 :

물론
t=# delete from t where i = 1540; 
DELETE 2 
Time: 941.684 ms 
t=# select count(1),i from t where i::text = (select (most_common_vals::text::text[])[1] from pg_stats where tablename = 't' and attname='i') group by i; 
count | i 
-------+--- 
(0 rows) 

Time: 1876.136 ms 
t=# analyze t; 
ANALYZE 
Time: 77.108 ms 
t=# select count(1),i from t where i::text = (select (most_common_vals::text::text[])[1] from pg_stats where tablename = 't' and attname='i') group by i; 
count | i 
-------+------- 
    2 | 41377 
(1 row) 

Time: 1878.260 ms 

당신이 한 가장 빈번한 값 다음, 실패 확률이 감소 더에 의존하는 경우, 그러나 다시 - 같은 방법은 통계 "신선도"에 따라 달라집니다.

+0

당신은 당신의 솔루션을 '신뢰할 수 없음'으로 묘사 한 이유에 대해 자세히 설명 할 수 있습니다. 고마워. –