You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL表插入指定规则的100条测试数据失败,求解决方案

解决PostgreSQL插入随机测试数据的问题

你的问题出在PostgreSQL对无关联标量子查询的优化上:那些嵌套的SELECT val FROM unnest(...) ORDER BY random() LIMIT 1子查询没有和外部的generate_series关联,优化器会将其视为常量,只执行一次,所以所有行都复用同一个随机结果。

同时你的INSERT语句还漏掉了contract列的赋值,以下是两种可行的解决方案:

方案1:通过数组索引生成随机值(简洁高效)

直接利用random()计算数组的随机索引,这种方式性能最优:

INSERT INTO test (contract, amount0, amount1, price)
SELECT
  -- 从3个contract值中随机选
  (ARRAY['abc', 'klm', 'xyz'])[floor(random() * array_length(ARRAY['abc', 'klm', 'xyz'], 1)) + 1],
  -- 从5个amount值中随机选
  (ARRAY[50, 60, 80, 100, 200])[floor(random() * array_length(ARRAY[50, 60, 80, 100, 200], 1)) + 1],
  (ARRAY[50, 60, 80, 100, 200])[floor(random() * array_length(ARRAY[50, 60, 80, 100, 200], 1)) + 1],
  -- 从4个price值中随机选
  (ARRAY[1.5, 1.8, 2.1, 2.5])[floor(random() * array_length(ARRAY[1.5, 1.8, 2.1, 2.5], 1)) + 1]
FROM generate_series(1, 100);

原理:floor(random() * N)生成0到N-1的整数,加1后对应数组的1-based索引(PostgreSQL数组默认从1开始)。

方案2:使用LATERAL关联子查询(更灵活)

如果需要更复杂的随机逻辑,可以用LATERAL让子查询和外部的generate_series逐行关联,确保每次循环都重新生成随机值:

INSERT INTO test (contract, amount0, amount1, price)
SELECT
  c.val,
  a0.val,
  a1.val,
  p.val
FROM generate_series(1, 100) AS gs
-- 每个行都执行一次随机选择
CROSS JOIN LATERAL (SELECT val FROM unnest(ARRAY['abc', 'klm', 'xyz']) AS val ORDER BY random() LIMIT 1) AS c
CROSS JOIN LATERAL (SELECT val FROM unnest(ARRAY[50, 60, 80, 100, 200]) AS val ORDER BY random() LIMIT 1) AS a0
CROSS JOIN LATERAL (SELECT val FROM unnest(ARRAY[50, 60, 80, 100, 200]) AS val ORDER BY random() LIMIT 1) AS a1
CROSS JOIN LATERAL (SELECT val FROM unnest(ARRAY[1.5, 1.8, 2.1, 2.5]) AS val ORDER BY random() LIMIT 1) AS p;

LATERAL关键字强制子查询为外部查询的每一行单独执行,避免了优化器将其视为常量。

内容的提问来源于stack exchange,提问作者Westcoaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:33:30