错误:无法写入临时文件的块37583345:设备上没有剩余空间

时间:2019-12-11 02:44:51

标签: postgresql postgresql-12

我想要这样的输出:

obid     | sid_count
1        |  3
2        |  2
3        |  4

对象在custdata表上,而sid_count从标识符表获取。

示例数据为:

custdata
obid
1
2
3

identifier
obid | type
1    | SID
1    | SID
1    | XID
1    | SID
2    | SID
2    | SID
3    | SID
3    | SID
3    | XID
3    | SID
3    | SID

我尝试运行此查询:

select custdata.obid,
count (identifier.obid) filter (where identifier.type = 'SID') as sid_count
from myschema.custdata, myschema.identifier group by custdata.obid

大约花了一个小时,但出现错误:

[53100] ERROR: could not write block 37583345 of temporary file: No space left on device

客户数据约为6500万条记录。 该标识符大约有2.5亿条记录。

如何克服这个问题?为什么数据库需要写入磁盘?还是我需要重写查询?因为我无法在磁盘上添加更多空间。

谢谢。

1 个答案:

答案 0 :(得分:1)

问题是您无意间写了一个交叉联接:

from myschema.custdata, myschema.identifier

也就是说,一个表的2.5亿行中的每一个与另一表的6500万行中的每一个都联接在一起,从而产生16.25万亿个结果行。您的数据目录似乎没有足够的空间来缓存完成查询所需的临时文件,因此您的磁盘空间已用完。

作为解决方案,添加连接条件。

把握机会,学会再也不会写这样的联接。始终使用标准语法:

FROM a JOIN b ON <condition>

那样,除非您明确指定

,否则您不会忘记加入条件
FROM a CROSS JOIN b

将会更加明显。