非常に遅い複雑なクエリがいくつかあります。クエリを単純な複製に縮小することができました。 greatest
とlog
の組み合わせが原因のようですが、理由がわかりません。
完全な sql-fiddleの例 でクエリを実行します-クエリの_View the execution Plans
_も実行できます(sql-fiddleページのクエリ結果の下部にあるリンクを押してください)
slowクエリは次のとおりです。
_select count(value)
from (
SELECT log(greatest(1e-9, x)) as value
from (select generate_series(1, 20000, 1) as x) as d
) t;
_
一連の20kの数値を生成し、log(greatest())
を使用します。このクエリには約1.5秒かかります。
ログの計算には時間がかかると思いましたが、次のクエリも高速です(〜5ms):
_select count(value)
from (
SELECT log(x) as value
from (select generate_series(1, 20000, 1) as x) as d
) t;
_
テストと同じようにgreatest
とlog
を交換しました-これも高速です(〜5ms):
_select count(value)
from (
SELECT greatest(1e-9, log(x)) as value
from (select generate_series(1, 20000, 1) as x) as d
) t;
_
3つのクエリすべての_QUERY PLANS
_は同じです。
_Aggregate (cost=22.51..22.52 rows=1 width=8)
-> Result (cost=0.00..5.01 rows=1000 width=4)
_
最初のクエリが非常に遅い理由を誰かが説明できますか-おそらく誰かが回避策を知っていますか?
これらすべてで同様の結果が得られます(最初のクエリは速度が遅くなります)。
count(value)
をcount(*)
またはcount(1)
(1番)に変更すると、クエリが高速になります
ここでは、2つの異なるログ関数log(numeric,numeric)
とlog(double precision)
を呼び出しています。最初の関数は2番目の関数よりもはるかに低速です。
以下のEXPLAIN(ANALYZE、VERBOSE)で関数呼び出しがどのように異なるか、PostgreSQL 11.5(Linux Ubuntu)で実行することに注意してください。
遅いバージョン:
_explain (analyze, verbose) select count(value)
from (
SELECT log(greatest(1e-9, x)) as value
from (select generate_series(1, 20000, 1) as x) as d
) t;
QUERY PLAN
-------------------------------------------------------------------------------------------------------
Aggregate (cost=25.02..25.03 rows=1 width=8) (actual time=1174.349..1174.349 rows=1 loops=1)
Output: count(log('10'::numeric, GREATEST(0.000000001, ((generate_series(1, 20000, 1)))::numeric)))
-> ProjectSet (cost=0.00..5.02 rows=1000 width=4) (actual time=0.004..1.310 rows=20000 loops=1)
Output: generate_series(1, 20000, 1)
-> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1)
Planning Time: 0.123 ms
Execution Time: 1174.385 ms
_
高速バージョン:
_explain (analyze, verbose) select count(value)
from (
SELECT log(greatest(1e-9::float, x)) as value
from (select generate_series(1, 20000, 1) as x) as d
) t;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Aggregate (cost=25.02..25.03 rows=1 width=8) (actual time=6.693..6.693 rows=1 loops=1)
Output: count(log(GREATEST('1e-09'::double precision, ((generate_series(1, 20000, 1)))::double precision)))
-> ProjectSet (cost=0.00..5.02 rows=1000 width=4) (actual time=0.004..2.561 rows=20000 loops=1)
Output: generate_series(1, 20000, 1)
-> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1)
Planning Time: 0.096 ms
Execution Time: 6.731 ms
_
greatest()
は責任を負いません。log(x)
のみを使用したクエリを検討すると、x
をnumeric
にキャストすると、greatest()
。