【问题标题】:Optimize a MAX aggregated query involving various tables优化涉及各种表的 MAX 聚合查询
【发布时间】:2012-03-06 10:01:14
【问题描述】:

我有一些表或多或少是这样的(我将使用一个更简单的域以便解释更清楚):

Trades
----------
ID
Seller_ID
Trade_Date

Sellers
-------
ID
Department_ID

我想获得每个部门的最新交易。查询类似于:

SELECT Department_ID, MAX(Trade_Date) FROM 
Trades, Sellers
WHERE Trades.Seller_ID = Sellers.ID
GROUP BY Sellers.Department_ID

Trades 表有一个日期索引,因此可用于加快查询速度,但我注意到查询在某些部门运行得很快(对 id 进行硬编码),而对另一些部门则运行得很慢。

我推断这是因为每个部门的交易量存在巨大差异。数据库正在对排序后的索引进行顺序扫描以获得第一次出现,而那些在很久以前进行最新销售的部门将需要在索引中走得很远。

我当前的解决方案是将最新的查询结果存储在辅助表中,并使新查询递增(按已在辅助表中的最新日期进行过滤)。它解决了这个问题,因为查询运行非常频繁,现在索引扫描只需要考虑几秒钟的交易。

但我认为应该有一个更优雅的解决方案。我知道如果聚合是由卖方而不是部门进行的,那么复合索引肯定会有所帮助,但我认为不允许建立生成不同表的索引......

【问题讨论】:

  • 您是否尝试过针对 Seller_ID 和 Trade_date 的复合索引?另外,两个表中的记录数是多少?
  • 我已经检查过了,当前架构上已经有这样的索引。这个数字是每周大约 300 万笔交易。查询需要几秒钟,但应该几乎是瞬间完成的。
  • 鉴于这种数据量和查询响应要求,您现有的方法对我来说是最好的 - 但其他人可能有更好的主意......
  • sellers.department_id 有什么用,一个未提及的表的外键,或者一个卖家的候选键?请添加(部分)相关的表定义,这将节省我们大量的猜测和输入。

标签: sql postgresql query-optimization aggregate-functions


【解决方案1】:

您是否考虑过使用物化视图,或者您是否使用 postgres 自行构建类似的东西?如果插入操作不像选择那样时间紧迫,那么我会考虑采用这种方式。

postgres中有一篇关于MV的文章:

http://tech.jonathangardner.net/wiki/PostgreSQL/Materialized_Views

【讨论】:

  • 不幸的是,插入更为重要!我不想让插入性能下降太多
  • 您是否考虑过类似的工作可以为您完成这项工作(意味着具有聚合结果的表每 30 秒更新一次或类似的东西)?我找不到任何关于 postgresql 的自治事务的信息来直接使用触发器实现这样的功能(似乎它不支持类似的东西)。你也可以看看他们的通知系统:postgresql.1045698.n5.nabble.com/…
猜你喜欢
  • 1970-01-01
  • 2010-12-18
  • 2010-12-06
  • 2017-02-03
  • 2021-09-03
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 2015-10-05
相关资源
最近更新 更多