当我运行此查询时:
UPDATE myTable SET x = (SELECT round(random()*100));
x
的所有记录都具有相同的值。这是有道理的。
当我运行此查询时:
UPDATE myTable SET x = round(random()*100);
它会更新表格中的所有记录,并且对于每条记录,x
的值都不同。
我想知道第二个查询在后台发生了什么。它是否为每个记录ID(1 .... n)运行更新查询?
我猜它的工作方式类似于触发器,更新前的每一行都是
实际发生了什么?
答案 0 :(得分:3)
这很简单,真的。函数random()
定义为VOLATILE
。
如果将其放入子查询中,则会生成一个包含单行的派生表。 Postgres可以实现结果并多次在外部查询中重用它。
否则Postgres会为每一行调用该函数。这就是必须如何处理VOLATILE
函数的方法。 Per documentation on function volatility:
VOLATILE
函数可以执行任何操作,包括修改数据库。 它可以在连续的调用中返回不同的结果 参数。优化器不做任何关于行为的假设 这样的功能。 使用volatile函数的查询将重新评估 每行都有功能,需要它的值。
大胆强调我的。