【问题标题】:SQL performance tuning with EXPLAIN使用 EXPLAIN 调优 SQL 性能
【发布时间】:2016-08-14 19:27:16
【问题描述】:

我有一张大桌子(~44 GB,421631931 行)

我正在尝试优化这种类型的 SQL 查询:

SELECT fid, sid, dsc_entry, clstr_first_entry, date_part('epoch',start_time)::numeric(20,7) AS time_epoch
FROM frames
WHERE (sid = 1)
AND start_time <= to_timestamp('1471161210.776')
ORDER BY start_time DESC
LIMIT 1;

到目前为止,我已经在start_time列上设置了索引:

"idx_start_time" btree (start_time) CLUSTER

当我运行EXPLAIN 时,我得到了这个计划:

Limit  (cost=0.57..0.92 rows=1 width=24)
  ->  Index Scan Backward using idx_start_time on frames  (cost=0.57..19347837.35 rows=55108378 width=24)
        Index Cond: (start_time <= '2016-08-14 09:53:30.776+02'::timestamp with time zone)
        Filter: (sid = 1)

这对我来说看起来不错(请注意,我以前从未尝试过以这种方式优化数据库),但查询仍然需要大约 80 秒才能完成。

你能指出我,我怎样才能加快速度? (磁盘空间不是问题)

谢谢, 彼得。

【问题讨论】:

  • 好吧,date_part 不利于运行时间 - 你确定需要它吗?
  • @mszymborski 好建议,date_part 用于在我的 C++ 应用程序(使用 libpqxx)中简化日期解析。我会尝试找出是否有更好的方法。

标签: sql postgresql query-optimization sql-execution-plan


【解决方案1】:

对于这个查询:

SELECT fid, sid, dsc_entry, clstr_first_entry, 
       date_part('epoch', start_time)::numeric(20,7) AS time_epoch
FROM frames
WHERE (sid = 1) AND start_time <= to_timestamp('1471161210.776')
ORDER BY start_time DESC
LIMIT 1;

我会推荐一个关于frames(sid, start_time) 的索引。

【讨论】:

  • 我已经在frames(start_time, sid) 上有一个唯一索引,但它似乎没有在计划中使用。有区别吗?
  • @PetrMánek 。 . .有一个主要区别。索引中列的顺序对于某些查询非常重要。在这种情况下,相等条件为sid,因此对于最佳索引,它应该是第一个键。
  • 谢谢,我今天学到了一些东西。我会重新索引并回复你。
  • 我已经创建了索引,运行了ANALYZEVACUUM ANALYZE但是没有任何效果。计划看起来还是一样。有什么问题?
  • sid 有多少个不同的值?也许它不是很有选择性。
【解决方案2】:

问题在于顺序,因为它是索引的倒数。 尝试使用:

CREATE INDEX ix ON frames (start_time DESC NULLS LAST);

desc 的顺序需要额外的时间来处理临时表中的数据。

【讨论】:

  • 我没想到。我将尝试创建索引。对于尽职调查,start_timesid 都是 NOT NULL
  • 好的,丢弃“NULL LAST”;尝试其余的;P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 2016-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多