これはおそらく速くなるが、あまりにも信頼性がない解決策になります。
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
、故障の可能性が減少するが、再びされている - このような方法は、統計の「新鮮さ」に依存します。
コードはうまくいきませんか?質問は何ですか? –
クエリは1000万行のデータセットで2分かかります。 –
はDB側で処理されます - psycopg2ではありません –