首页 > 解决方案 > 如何防止我的 SQL 子查询在 PostgreSQL 中缓存数据?

问题描述

我正在尝试使用 Postgresql 11插入测试数据来测试postgresql 分区。

这是我的桌子:

CREATE TABLE measurement (
    city_id         int not null,
    logdate         date not null,
    peaktemp        int,
    unitsales       int
);

这是我插入测试数据的声明:

explain insert into measurement(
  city_id,
  logdate,
  peaktemp,
  unitsales
)
select
  ( 
    select (random() * 10000)::int + (generator*0) as city_id 
  ),
  ( 
    select 
        * 
    from 
        (select * from generate_series('2006-01-01'::timestamp,
                                       '2006-12-31'::timestamp,
                                       '1 day')) as rng
    order by
        random()
    limit 1
  ) as logdate,
  ( 
    select (random() * 10000)::int + (generator*0) as peaktemp 
  ),
  ( 
    select (random() * 10000)::int + (generator*0) as unitsales 
  )
from generate_series(1, 1000) as generator

问题是:当我运行此语句时,生成该字段的 select 子查询logdate似乎已被缓存,并且该表measurement包含该字段的单个值logdate

因此,如果我运行以下查询:

select distinct(logdate)
from measurement

我只得到一个值: 2006-02-10

如何防止缓存的副作用?

标签: sqlpostgresql

解决方案


正如您所观察到的,ORDER BY对于子查询计算一次,这样对于在外部查询中生成的每一行,选定的行将是相同的。因此ORDER BY,即使您调用random().

尝试这个:

SELECT
  (random() * 10000)::int AS city_id,
  '2006-01-01'::timestamp + random() * ('2006-12-31'::timestamp - '2006-01-01'::timestamp) AS logdate,
  (random() * 10000)::int AS peaktemp,
  (random() * 10000)::int AS unitsales
FROM
generate_series(1,1000);

我不确定您的要求是什么,但我认为您不需要 1)一堆子选择或 2)所有对 的引用generator*0,所以我也删除了它们。

披露:我为EnterpriseDB (EDB)工作


推荐阅读