【问题标题】:Multiple optional query parameters with PostgreSQLPostgreSQL 的多个可选查询参数
【发布时间】:2018-06-16 23:00:00
【问题描述】:

我使用 PostgreSQL10,我想构建具有多个可选参数的查询。

用户必须输入区域名称,但可以选择不选择以下
事件、事件日期、类别、类别日期、样式的任意组合或任意组合

因此,完整的查询可能是“所有银行(类别),建于 1990 年(类别日期),具有现代建筑(风格),于 1992 年在纽约市(地区)地区进行了翻新(事件和事件日期) ”。

我的问题是所有这些都在不同的表中,由多对多表连接,所以我不能做类似的事情

SELECT * FROM mytable
WHERE (Event IS NULL OR Event = event) 

我不知道如果我只加入四张桌子会不会有什么好处。 我可以很容易地找到区域 ID,因为它是必需的,但除此之外,我不知道用户选择了什么。

关于如何使用 Postgre 解决此问题的任何建议?

谢谢

【问题讨论】:

  • 你快到了:SELECT * FROM mytable WHERE EXISTS (SELECT* FROM correlated_tables that_you_want WHERE conditions_that_you_want);

标签: postgresql database-design parameters many-to-many query-performance


【解决方案1】:

动态构建整个查询并仅加入您知道将需要的表以应用用户过滤器可能是最佳,但这是不切实际的。您最好在完整的表集上创建一个视图。使用LEFT OUTER JOINs 确保您不会意外过滤掉有效组合并为您的表建立索引,以确保查询规划器可以快速浏览表图。然后使用 WHERE 子句查询视图,该子句仅反映您要应用的过滤器。

如果性能成为问题并且您不介意使用非实时数据,您可以使用materialized view 来缓存结果。物化视图可以直接被索引,但这是一个非常激进的变化,所以除非必须,否则不要这样做。

【讨论】:

  • 是的,无论如何我都会使用索引。那么,您建议使用连接视图吗?但这不会阻止IFs 的使用,并且查询计划器会缓存错误的计划,因此接下来的查询会变慢。经过一些研究,我认为动态 sql 在速度和维护方面是正确的做法。我以前在实践中从未使用过动态 sql,我还没有代码,但至少在理论上,我相信这是要走的路。也许有更好的理由拒绝动态 sql?如果有请详细说明。谢谢
  • 你不需要条件。获取您可能需要的所有数据,并将其过滤为您当前需要的数据。从集合的角度思考,而不是迭代和评估。视图是动态运行的,因此查询计划器将能够应对。动态 SQL 是不得已而为之的工具:它非常复杂和脆弱,除非没有其他合理的方法可以实现您的目标,否则应该避免使用它。
  • 因此,实际上,查看用户插入并相应地构建了 FROM 和 WHERE 子句,作为字符串。然后将这些字符串附加到视图,然后执行。好的,视图是动态运行的,但每次都使用不同的参数,因为每次都会插入不同的参数。或者,也许我没有得到什么。再次感谢
  • 否:使用一致的FROM 子句创建一个视图,该子句连接您将需要的所有表。然后SELECT * FROM myview WHERE... 并将您的特定过滤器应用于整个数据集。你的 WHERE 子句是唯一改变的部分。
  • 查看此类查询并不能解决其速度和维护问题,因为 WHERE 部分仍然不是静态的。更多信息hereherehere。请记住,最后一个链接中的最后一个示例看起来像你建议的那样,但是关于 SQL 2008。毕竟我将使用动态 sql
猜你喜欢
  • 2021-05-29
  • 2010-09-24
  • 2017-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
  • 2020-09-08
相关资源
最近更新 更多