【问题标题】:How to improve performance of queries which use table-valued functions?如何提高使用表值函数的查询的性能?
【发布时间】:2013-04-06 20:37:44
【问题描述】:

我有一个表格查询:

SELECT a.id, b.colb, c.colc, d.cold, ...
FROM a JOIN b on a.id=b.id
       JOIN c on a.id=c.id
       JOIN d on a.id=d.id
       JOIN e on a.id=e.id
       ...

这里的每个表实际上都是一个表值函数。该查询的运行时间超过一分钟,但是当我手动创建临时表 (CREATE TEMPORARY TABLE ax as SELECT * from a) 并针对这些临时表运行查询时,需要几毫秒(创建表也需要几毫秒)。

什么可能导致如此大的性能差异(至少两个数量级)?

【问题讨论】:

  • 如果您可以在查询中显示您的 PostgreSQL 版本和explain analyze 的输出,将会很有帮助

标签: sql postgresql database-performance


【解决方案1】:

PostgreSQL 优化器可能会选择以loop join 的形式执行您的连接。也就是说,它将评估每个左侧行的函数调用。

您使用临时表的解决方案是避免这种情况的绝佳方法。即使优化器再次选择loop join,结果也会在临时表中进行大量查找。查找比重复评估函数便宜一个数量级。

【讨论】:

  • 即使函数被标记为STABLE(即不需要重复评估)也是这样吗?
  • STABLE 只是说该函数只需为同一组值评估一次。可能仍然需要每行评估一次。由于您能够预取函数的结果,这表明您的函数比稳定函数更不稳定,并且不依赖于任何行。 STABLE 不会告诉优化器这一切。
【解决方案2】:

尝试 CTE:

with
    a as (select * from a),
    b as (select * from b),
    c as (select * from c),
    d as (select * from d),
    e as (select * from e)
select a.id, b.colb, c.colc, d.cold, ...
from a
    join b on a.id=b.id
    join c on a.id=c.id
    join d on a.id=d.id
    join e on a.id=e.id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 2017-01-21
    相关资源
    最近更新 更多