Moh*_*ash 5 postgresql generate-series
在Bruce Momjian的博客文章"通过SQL生成随机数据"中,他使用以下代码生成5个随机字符串:
SELECT
(
SELECT string_agg(x, '')
FROM (
SELECT chr(ascii('a') + floor(random() * 26)::integer)
FROM generate_series(1, 40 + b * 0) as f(g)
) AS y(x)
) AS result
FROM generate_series(1,5) as a(b);
result
------------------------------------------
plwfwcgajxdygfissmxqsywcwiqptytjjppgrvgb
sjaypirhuoynnvqjdgywfsfphuvzqbbilbhakyhf
ngtabkjfqibwahlicgisijatliuwgbcuiwujgeox
mqtnyewalettounachwjjzdrvxbbbpzogscexyfi
dzcstpsvwpefohwkfxmhnlwteyybxejbdltwamsx
(5 rows)
Run Code Online (Sandbox Code Playgroud)
我想知道为什么第6行的'b*0'是必需的.当我删除它时,结果更改为5个完全相似的字符串,这意味着Postgres缓存了外部选择表达式(结果)!
我无法找到Postgres中的表达式缓存是如何工作的.根据文档, random()函数被标记为VOLATILE,所以,我希望任何表达式都依赖于它也是易变的.
表达式缓存如何在Postgres中起作用?是否记录在任何地方?为什么'b*0'禁用了random()没有的缓存?
更新:
为了研究这个问题,我将'b*0'移到了floor()调用内,与random()处于相同的位置/级别:
...
SELECT chr(ascii('a') + floor(random() * 26 + b * 0)::integer)
FROM generate_series(1, 40) as s(f)
...
Run Code Online (Sandbox Code Playgroud)
结果仍未缓存; 不同的字串.
更新:显示问题的另一个示例
create sequence seq_test;
SELECT (SELECT nextval('seq_test')) FROM generate_series(1,5);
?column?
----------
1
1
1
1
1
(5 rows)
Run Code Online (Sandbox Code Playgroud)
嗯,random()
它本身是不稳定的,因此您不会得到具有重复到末尾的相同字符的字符串。
如果您查看有和没有的查询计划,b*0
您将看到:
和b*0
:
Function Scan on generate_series a (cost=0.00..37530.00 rows=1000 width=4)
SubPlan 1
-> Aggregate (cost=37.51..37.52 rows=1 width=32)
-> Function Scan on generate_series (cost=0.01..25.01 rows=1000 width=0)
Run Code Online (Sandbox Code Playgroud)
没有b*0
:
Function Scan on generate_series a (cost=37.52..47.52 rows=1000 width=0)
InitPlan 1 (returns $0)
-> Aggregate (cost=37.50..37.51 rows=1 width=32)
-> Function Scan on generate_series (cost=0.00..25.00 rows=1000 width=0)
Run Code Online (Sandbox Code Playgroud)
如果 PostgreSQL 确定内部聚合不依赖于a
,则将其作为 求值一次InitPlan
,并且内部表达式的波动性与否无关紧要。通过引入子查询对 的依赖性a
,即使其成为相关子查询,必须对 的每一行重新进行评估a
。
归档时间: |
|
查看次数: |
1070 次 |
最近记录: |