Postgres 会将 WHERE 子句下推到带有窗口函数(聚合)的 VIEW 中吗?

2023-11-25

的文档Pg的窗口函数说:

窗口函数考虑的行是查询的 FROM 子句生成的“虚拟表”的行,并通过其 WHERE、GROUP BY 和 HAVING 子句(如果有)进行过滤。例如,由于不满足 WHERE 条件而被删除的行不会被任何窗口函数看到。查询可以包含多个窗口函数,这些窗口函数通过不同的 OVER 子句以不同的方式对数据进行切片,但它们都作用于该虚拟表定义的同一行集合。

但是,我没有看到这一点。在我看来,选择过滤器非常靠近左边距和顶部(最后完成的事情)。

=# EXPLAIN SELECT * FROM chrome_nvd.view_options where fkey_style = 303451;
                                                      QUERY PLAN                                                      
----------------------------------------------------------------------------------------------------------------------
 Subquery Scan view_options  (cost=2098450.26..2142926.28 rows=14825 width=180)
   Filter: (view_options.fkey_style = 303451)
   ->  Sort  (cost=2098450.26..2105862.93 rows=2965068 width=189)
         Sort Key: o.sequence
         ->  WindowAgg  (cost=1446776.02..1506077.38 rows=2965068 width=189)
               ->  Sort  (cost=1446776.02..1454188.69 rows=2965068 width=189)
                     Sort Key: h.name, k.name
                     ->  WindowAgg  (cost=802514.45..854403.14 rows=2965068 width=189)
                           ->  Sort  (cost=802514.45..809927.12 rows=2965068 width=189)
                                 Sort Key: h.name
                                 ->  Hash Join  (cost=18.52..210141.57 rows=2965068 width=189)
                                       Hash Cond: (o.fkey_opt_header = h.id)
                                       ->  Hash Join  (cost=3.72..169357.09 rows=2965068 width=166)
                                             Hash Cond: (o.fkey_opt_kind = k.id)
                                             ->  Seq Scan on options o  (cost=0.00..128583.68 rows=2965068 width=156)
                                             ->  Hash  (cost=2.21..2.21 rows=121 width=18)
                                                   ->  Seq Scan on opt_kind k  (cost=0.00..2.21 rows=121 width=18)
                                       ->  Hash  (cost=8.80..8.80 rows=480 width=31)
                                             ->  Seq Scan on opt_header h  (cost=0.00..8.80 rows=480 width=31)
(19 rows)

这两个 WindowAgg 实质上将计划更改为似乎永远无法完成的更快的计划

                                                                       QUERY PLAN                                                                       
--------------------------------------------------------------------------------------------------------------------------------------------------------
 Subquery Scan view_options  (cost=329.47..330.42 rows=76 width=164) (actual time=20.263..20.403 rows=42 loops=1)
   ->  Sort  (cost=329.47..329.66 rows=76 width=189) (actual time=20.258..20.300 rows=42 loops=1)
         Sort Key: o.sequence
         Sort Method:  quicksort  Memory: 35kB
         ->  Hash Join  (cost=18.52..327.10 rows=76 width=189) (actual time=19.427..19.961 rows=42 loops=1)
               Hash Cond: (o.fkey_opt_header = h.id)
               ->  Hash Join  (cost=3.72..311.25 rows=76 width=166) (actual time=17.679..18.085 rows=42 loops=1)
                     Hash Cond: (o.fkey_opt_kind = k.id)
                     ->  Index Scan using options_pkey on options o  (cost=0.00..306.48 rows=76 width=156) (actual time=17.152..17.410 rows=42 loops=1)
                           Index Cond: (fkey_style = 303451)
                     ->  Hash  (cost=2.21..2.21 rows=121 width=18) (actual time=0.432..0.432 rows=121 loops=1)
                           ->  Seq Scan on opt_kind k  (cost=0.00..2.21 rows=121 width=18) (actual time=0.042..0.196 rows=121 loops=1)
               ->  Hash  (cost=8.80..8.80 rows=480 width=31) (actual time=1.687..1.687 rows=480 loops=1)
                     ->  Seq Scan on opt_header h  (cost=0.00..8.80 rows=480 width=31) (actual time=0.030..0.748 rows=480 loops=1)
 Total runtime: 20.893 ms
(15 rows)

这是怎么回事?我该如何解决?我正在使用 Postgresql 8.4.8。这是实际视图正在执行的操作:

 SELECT o.fkey_style, h.name AS header, k.name AS kind
   , o.code, o.name AS option_name, o.description
     , count(*) OVER (PARTITION BY h.name) AS header_count
     , count(*) OVER (PARTITION BY h.name, k.name) AS header_kind_count
   FROM chrome_nvd.options o
   JOIN chrome_nvd.opt_header h ON h.id = o.fkey_opt_header
   JOIN chrome_nvd.opt_kind k ON k.id = o.fkey_opt_kind
  ORDER BY o.sequence;

不,PostgreSQL 只会在没有聚合的 VIEW 上下推 WHERE 子句。 (窗口函数被视为聚合)。

我认为这只是一个实现限制

x:我想知道必须采取什么措施来推动 在本例中,WHERE 子句被删除。

规划者必须知道 WindowAgg 本身不会添加选择性,因此将 WHERE 向下推是安全的吗?

埃文·卡罗尔;我想与计划者一起做很多非常复杂的工作

And,

埃文卡罗尔:不。视图上的过滤条件适用于output视图的,并且仅当视图不涉及聚合时才被下推

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Postgres 会将 WHERE 子句下推到带有窗口函数(聚合)的 VIEW 中吗? 的相关文章

随机推荐

  • Android:TimePicker setIs24HourView 不起作用

    我正在尝试以 24 小时格式使用 TimePicker 并且我正在使用 setIs24HourView true 但我仍然没有在 TimePicker 上获得 24 小时格式 这是我在 Activity 的 onCreate 中的代码 ti
  • Python While 循环突破问题

    我的问题是关于 while 循环的标志 这有效 但不像我想象的那样 我认为我不明白某些事情 所以如果有人能够解释 那就太好了 根据我的理解 一旦满足我的条件之一 这应该会打破循环 因此 如果我输入 q 它应该会中断并停止循环 但发生的情况是
  • Keycloak:缺少领域公钥

    当我访问 keycloak 管理控制台 远程 并创建客户端时 keycloak OIDC JSON 没有公钥 我希望 JSON 中有类似的内容 realm public key MIIBIjANBg 最新的 keycloak 中的 keyc
  • 如何为私有子网中部署的服务配置api网关?

    我在私有子网中部署了一个 Web 服务 而在公共子网中没有 ELB 现在我想把它曝光给公众 我可以使用API 网关作为http代理吗 公开 有人知道该怎么做吗 该服务必须是公开的 API Gateway 才能连接到它 您可以使用 SSL 客
  • 将单词拆分为所有可能的“子词” - 所有可能的组合

    我正在尝试将一个单词拆分为子单词 所有可能的排列 Input Bang Output B ang Ba ng Ban g B a ng B an g Ba n g B a n g 我希望我涵盖了所有可能的安排 Bang 的方法 我想了很久却
  • 使用 sed,在模式上方或下方插入一行? [复制]

    这个问题在这里已经有答案了 我需要通过在唯一模式的正下方或上方插入一行或多行来编辑大量文件 请建议如何使用sed awk perl 或其他任何东西 在外壳中 谢谢 例子 some text lorem ipsum dolor sit ame
  • 连接python套接字和java套接字

    我一直在尝试在 Java 客户端套接字和 Python 服务器套接字之间发送一个简单的字符串 这是服务器套接字的代码 HOST PORT 12000 s socket socket socket AF INET socket SOCK ST
  • 如何使用 Cmake 和 NASM 构建二进制文件

    我正在学习 x64 并且我讨厌 make 所以我试图让 cmake 使用 NASM 构建二进制文件 cmake 大致支持这一点 但文档很糟糕 这就是我现在所做的工作 将堆栈溢出中的内容拼凑在一起 然后删除所有不会破坏构建的内容 cmake
  • 绑定到当前项目 (WPF)

    我正在尝试绑定一个ListView控制到一个DataTable 但 WPF 绑定系统似乎抱怨我指定的绑定路径 举个例子 一个GridViewColumn定义如下
  • CMake 对 C 文件禁用 -std=c++11 标志

    我正在尝试建立bkchaind 一种构建选项是使用 cmake 因此我使用 Homebrew OSX 10 9 1 安装它 当我做cmake不过 我得到 2 Building C object json rpc cpp src jsonrp
  • 在 Java 中 fork 一个进程

    是否可以将正在执行的 程序 从单个执行序列创建为两个子程序的完整分支 生成的子程序完全相同 它们具有相同的执行顺序和值 但现在它们是两个不同的程序 这就像创建一个对象的克隆 从而为我们提供了两个相同类型的不同对象来处理 但这里我们想要创建一
  • range over 存储切片的接口{}

    假设您有一个接受的函数t interface 如果确定t是一个切片 我该怎么做range在那片上 func main data string one two three test data moredata int 1 2 3 test d
  • List[Int] 和 List[Integer] 类型擦除的差异

    为什么List scala Int 键入擦除List Object whilst Integer in List java lang Integer 似乎 被保存 例如 javap for object Foo def fooInt Lis
  • IE (HTTPS):从 php 文件生成 pdf 不起作用

    这是我的问题 我正在尝试调用页面 foo php docID bar 并将 PDF 返回到屏幕 该 PDF 作为 BLOB 存储在数据库中 这是我的代码中实际返回 PDF 的部分 docID isset REQUEST docID REQU
  • 来自 Android Studio 的详细构建日志

    使用 Android Studio 构建时如何获取详细日志 包括编译器和链接器的命令行参数 我刚刚从 Ant Android mk 构建过渡到 Android Studio 构建 在旧系统中 我能够通过执行以下操作来了解编译器是如何被调用的
  • 如何在多个别名上定义递归 Python 类型?

    我想要这个逻辑类型结构 from typing import List Dict Union ObjectType Dict str EntryType ListType List EntryType EntryType Union str
  • n 级可扩展列表视图

    如何显示n级可扩展列表视图android 我只得到3级可扩展的示例 参考这个 link 请指导或分享我在android中多级可扩展显示的合适示例 Thanks 根据这个example public View getChildView int
  • valgrind memcheck 是否支持检查 mmap

    我正在尝试 valgrind 来检测内存泄漏 它在堆泄漏 即从 malloc 或 new 分配内存 方面效果很好 但是 它支持检查 Linux 中的 mmap 泄漏吗 谢谢 张 不直接 很难调试 看看valgrind h VALGRIND
  • 更改为 Android SDK 26 后工具栏中的图标被压扁

    将我的应用程序从编译 定位 SDK v25 更改为 SDK v26 后 我的应用程序工具栏中的所有菜单图标现在都被压扁 压扁 拉伸 这是相关的布局代码
  • Postgres 会将 WHERE 子句下推到带有窗口函数(聚合)的 VIEW 中吗?

    的文档Pg的窗口函数说 窗口函数考虑的行是查询的 FROM 子句生成的 虚拟表 的行 并通过其 WHERE GROUP BY 和 HAVING 子句 如果有 进行过滤 例如 由于不满足 WHERE 条件而被删除的行不会被任何窗口函数看到 查