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

クエリは1000万行のデータセットで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 

と最後だけをチェック最もユニークな値の1つで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されます。したがって、データ配信に関する新しく集計された統計がない可能性があります。例えば私のサンプルでは:あなただけの1最頻値、より多くに依存している場合はもちろんの

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

あなたはあなたのソリューションを「信頼できない」と記述した理由を詳しく説明できますが、これは信頼できない場合があります。どうもありがとう。 –

関連する問題