当前位置: 首页 > 知识库问答 >
问题:

PostgreSQL-SUM和LEFT JOIN上的查询优化

张翰海
2023-03-14

我用to_char()来计算这个月的时间,这在两个表中很常见,即表1表2

但在表2中,我有日期和月份。

我还在表1上创建了一个索引。如果我只写相同的查询表1,我得到的结果在1000ms内。

我取值的总和,并使用左连接组合结果。

问题是这样的。

SELECT
    "month", -- Table2
    sum("value1"), -- Table2
    sum("value2") -- Table1
FROM Table2
LEFT JOIN Table1 ON
    Table2."month" = to_char(Table1.Date, 'Mon-yy')
WHERE Table2.Date BEtween '2014-01-01' AND '2014-03-01'
GROUP BY "month"

解释问题:

"GroupAggregate  (cost=88133.61..3688425.12 rows=2 width=15)"
"  ->  Merge Left Join  (cost=88133.61..2707006.48 rows=130855816 width=15)"
"        Merge Cond: (Table2.month = (to_char((Table1.date)::timestamp with time zone, 'Mon-yy'::text)))"
"        ->  Sort  (cost=8922.32..9056.34 rows=53609 width=11)"
"              Sort Key: Table2.month"
"              ->  Seq Scan on Table2(cost=0.00..3885.28 rows=53609 width=11)"
"                    Filter: ((date >= '2014-01-01'::date) AND (date   Materialize  (cost=79211.29..81652.22 rows=488186 width=8)"
"              ->  Sort  (cost=79211.29..80431.75 rows=488186 width=8)"
"                    Sort Key: (to_char((Table1.date)::timestamp with time zone, 'Mon-yy'::text))"
"                    ->  Seq Scan on Table1(cost=0.00..19735.86 rows=488186 width=8)"

目前,我在表1中大约有500k行。

每天我都会更新表,将大约3到4k记录更新到表1。

查询一直在运行。

我没有得到任何结果。

谁能告诉我哪里出了问题吗?

共有1个答案

佟颖逸
2023-03-14

为了让查询“高效”运行,需要两个索引。根据解释判断,表2的日期栏需要一个索引。

使用btree(date)在table2上创建索引;

表1需要一个带有月名和日数的计算索引,例如“Apr-14”。

使用btree(to_char(date,'Mon-yy'))在表1上创建索引

[编辑,正如一个名为_no _的_horse _所说的那样,这是行不通的,因为to _char不是不可变的——你可以通过编写自己的不可变函数来解决这个问题,但如果你只存储一个日期列,它会简单得多!]

也就是说,文本匹配比日期或数字要慢,如果你想对信息排序,你只能按字母顺序排序。

 类似资料:
  • 例如,我在MongoDB中有以下数据: 现在我想查询“SUM传入的数量在11 - 12之间”(结果应该是500),我如何使用Mongo Shell来做到这一点?

  • 问题内容: 请帮助我处理使用带有GROUP和SUM的LINQ进行查询的问题。 我希望: 从db.MYDATABASE中获取前25个项目 将所有结果按bs.PRODCODE分组 按每个bs的总和排序。 公司是“我的公司” 然后将数据管道到我的对象中 我很困惑,因为一旦我将其添加到混音中,我的变量就变得无用了。 问题答案: 我很困惑,因为一旦我将组添加到混合中,我的bs变量就变得无用了。 是的,因为您

  • 问题内容: 我正在对PostgreSQL数据库中的表运行查询。该数据库位于远程计算机上。该表具有约30个使用postgresql 分区功能的子表。 该查询将返回一个很大的结果集,大约有180万行。 在我的代码中,我使用spring jdbc支持,即方法JdbcTemplate.query,但未调用我的RowCallbackHandler。 我最好的猜测是postgresql jdbc驱动程序(我使

  • 问题内容: 说我们有一张桌子: 填充一些行: 我想确定何时更改了值。所以我的查询结果应该是: 我有一个连接和子查询的解决方案: 但这是非常低效的,并且对于具有许多行的表将非常慢地工作。 我相信使用PostgreSQL窗口函数可能会有更有效的解决方案? SQL小提琴 问题答案: 这就是我如何通过分析来做到这一点: 更新(一些解释): 分析功能充当后处理步骤。查询结果分为多个分组(),并且在分组的上下

  • 主要内容:SELECT 语句中的子查询使用,INSERT 语句中的子查询使用,UPDATE 语句中的子查询使用,DELETE 语句中的子查询使用子查询或称为内部查询、嵌套查询,指的是在 PostgreSQL 查询中的 WHERE 子句中嵌入查询语句。 一个 SELECT 语句的查询结果能够作为另一个语句的输入值。 子查询可以与 SELECT、INSERT、UPDATE 和 DELETE 语句一起使用,并可使用运算符如 =、<、>、>=、<=、IN、BETWEEN 等。 以下是子查询必须遵循的几个

  • 问题内容: 我有一张桌子,上面有我所有顾客购买的东西。我想选择上周(从周日开始的一周)中的所有条目。 我已经试过了: 但是我得到了上周的数据,包括本周的数据,我只想要上周的数据。 如何只获取上周的数据? 问题答案: 此条件将返回上周日至周六的记录: 有一个例子: 在对@ d456的回答中: 在间隔的两端不使用星期日的午夜吗? 没错,包括间隔两端的周日午夜。要在间隔结束时排除周日的午夜,必须使用运算