- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有 2 个表。它们的结构大致如下;不过,我已经更改了名称。
CREATE TABLE overlay_polygon
(
overlay_polygon_id SERIAL PRIMARY KEY,
some_other_polygon_id INTEGER REFERENCES some_other_polygon (some_other_polygon_id)
dollar_value NUMERIC,
geom GEOMETRY(Polygon,26915)
)
CREATE TABLE point
(
point_id SERIAL PRIMARY KEY,
some_other_polygon_id INTEGER REFERENCES some_other_polygon (some_other_polygon_id)
-- A bunch of other fields that this query won't touch
geom GEOMETRY(Point,26915)
)
point
在其 geom
列上有一个名为 spix_point
的空间索引,在其 some_other_polygon_id
上有一个索引专栏也是如此。
point
中大约有 500,000 行,point
中几乎所有行都与 overlay_polygon
中的某些行相交。最初,我的 overlay_polygon
表包含几行,这些行的面积非常小(大部分小于 1 平方米),并且在空间上不与 point
的任何行相交。删除点
中不与任何行相交的小行后,共有38行。
顾名思义,overlay_polygon
是一个多边形表,由 3 个其他表(包括 some_other_polygon
)的多边形叠加而成。特别是,我需要使用 dollar_value
和 point
上的一些列进行一些计算。当我打算删除不与任何点相交的行以加快将来的处理速度时,我最终查询了 COUNT 行。最明显的查询似乎如下。
SELECT op.*, COUNT(point_id) AS num_points
FROM overlay_polygon op
LEFT JOIN point ON op.some_other_polygon_id = point.some_other_polygon_id AND ST_Intersects(op.geom, point.geom)
GROUP BY op.overlay_polygon_id
ORDER BY op.overlay_polygon_id
;
这是它的EXPLAIN (ANALYZE, BUFFERS)
。
GroupAggregate (cost=544.45..545.12 rows=38 width=8049) (actual time=284962.944..540959.914 rows=38 loops=1)
Buffers: shared hit=58694 read=17119, temp read=189483 written=189483
I/O Timings: read=39171.525
-> Sort (cost=544.45..544.55 rows=38 width=8049) (actual time=271754.952..534154.573 rows=415224 loops=1)
Sort Key: op.overlay_polygon_id
Sort Method: external merge Disk: 897016kB
Buffers: shared hit=58694 read=17119, temp read=189483 written=189483
I/O Timings: read=39171.525
-> Nested Loop Left Join (cost=0.00..543.46 rows=38 width=8049) (actual time=0.110..46755.284 rows=415224 loops=1)
Buffers: shared hit=58694 read=17119
I/O Timings: read=39171.525
-> Seq Scan on overlay_polygon op (cost=0.00..11.38 rows=38 width=8045) (actual time=0.043..153.255 rows=38 loops=1)
Buffers: shared hit=1 read=10
I/O Timings: read=152.866
-> Index Scan using spix_point on point (cost=0.00..13.99 rows=1 width=200) (actual time=50.229..1139.868 rows=10927 loops=38)
Index Cond: (op.geom && geom)
Filter: ((op.some_other_polygon_id = some_other_polygon_id) AND _st_intersects(op.geom, geom))
Rows Removed by Filter: 13353
Buffers: shared hit=58693 read=17109
I/O Timings: read=39018.660
Total runtime: 542172.156 ms
但是,我发现这个查询运行得非常非常快:
SELECT *
FROM overlay_polygon
JOIN (SELECT op.overlay_polygon_id, COUNT(point_id) AS num_points
FROM overlay_polygon op
LEFT JOIN point ON op.some_other_polygon_id = point.some_other_polygon_id AND ST_Intersects(op.geom, point.geom)
GROUP BY op.overlay_polygon_id
) x ON x.overlay_polygon_id = overlay_polygon.overlay_polygon_id
ORDER BY overlay_polygon.overlay_polygon_id
;
它的EXPLAIN (ANALYZE, BUFFERS)
如下。
Sort (cost=557.78..557.88 rows=38 width=8057) (actual time=18904.661..18904.748 rows=38 loops=1)
Sort Key: overlay_polygon.overlay_polygon_id
Sort Method: quicksort Memory: 126kB
Buffers: shared hit=58690 read=17134
I/O Timings: read=9924.328
-> Hash Join (cost=544.88..556.78 rows=38 width=8057) (actual time=18903.697..18904.210 rows=38 loops=1)
Hash Cond: (overlay_polygon.overlay_polygon_id = op.overlay_polygon_id)
Buffers: shared hit=58690 read=17134
I/O Timings: read=9924.328
-> Seq Scan on overlay_polygon (cost=0.00..11.38 rows=38 width=8045) (actual time=0.127..0.411 rows=38 loops=1)
Buffers: shared hit=2 read=9
I/O Timings: read=0.173
-> Hash (cost=544.41..544.41 rows=38 width=12) (actual time=18903.500..18903.500 rows=38 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 2kB
Buffers: shared hit=58688 read=17125
I/O Timings: read=9924.154
-> HashAggregate (cost=543.65..544.03 rows=38 width=8) (actual time=18903.276..18903.379 rows=38 loops=1)
Buffers: shared hit=58688 read=17125
I/O Timings: read=9924.154
-> Nested Loop Left Join (cost=0.00..543.46 rows=38 width=8) (actual time=0.052..17169.606 rows=415224 loops=1)
Buffers: shared hit=58688 read=17125
I/O Timings: read=9924.154
-> Seq Scan on overlay_polygon op (cost=0.00..11.38 rows=38 width=8038) (actual time=0.004..0.537 rows=38 loops=1)
Buffers: shared hit=1 read=10
I/O Timings: read=0.279
-> Index Scan using spix_point on point (cost=0.00..13.99 rows=1 width=200) (actual time=4.422..381.991 rows=10927 loops=38)
Index Cond: (op.gopm && gopm)
Filter: ((op.some_other_polygon_id = some_other_polygon_id) AND _st_intersects(op.geom, geom))
Rows Removed by Filter: 13353
Buffers: shared hit=58687 read=17115
I/O Timings: read=9923.875
Total runtime: 18905.293 ms
如您所见,他们有可比较的成本估算,但我不确定这些成本估算的准确性。我对涉及 PostGIS 功能的成本估算持怀疑态度。自上次修改以来和运行查询之前,这两个表都运行了 VACUUM ANALYZE FULL
。
也许我只是无法阅读我的EXPLAIN ANALYZE
,但我不明白为什么这些查询的运行时间有如此大的不同。任何人都可以识别任何东西吗?我能想到的唯一可能性与LEFT JOIN
中涉及的列数有关。
根据@ChrisTravers 的建议,我增加了 work_mem
并重新运行第一个查询。我不认为这是一个显着的改进。
执行
SET work_mem='4MB';
(它是 1 MB。)
然后执行第一个查询给出了这些结果。
GroupAggregate (cost=544.45..545.12 rows=38 width=8049) (actual time=339910.046..495775.478 rows=38 loops=1)
Buffers: shared hit=58552 read=17261, temp read=112133 written=112133
-> Sort (cost=544.45..544.55 rows=38 width=8049) (actual time=325391.923..491329.208 rows=415224 loops=1)
Sort Key: op.overlay_polygon_id
Sort Method: external merge Disk: 896904kB
Buffers: shared hit=58552 read=17261, temp read=112133 written=112133
-> Nested Loop Left Join (cost=0.00..543.46 rows=38 width=8049) (actual time=14.698..234266.573 rows=415224 loops=1)
Buffers: shared hit=58552 read=17261
-> Seq Scan on overlay_polygon op (cost=0.00..11.38 rows=38 width=8045) (actual time=14.612..15.384 rows=38 loops=1)
Buffers: shared read=11
-> Index Scan using spix_point on point (cost=0.00..13.99 rows=1 width=200) (actual time=95.262..5451.636 rows=10927 loops=38)
Index Cond: (op.geom && geom)
Filter: ((op.some_other_polygon_id = some_other_polygon_id) AND _st_intersects(op.geom, geom))
Rows Removed by Filter: 13353
Buffers: shared hit=58552 read=17250
Total runtime: 496936.775 ms
好吧,这里有一种我以前没有注意到的好闻的味道(主要是因为我无法阅读 ANALYZE
输出)。抱歉,我没有早点注意到它。
Sort (cost=544.45..544.55 rows=38 width=8049) (actual time=271754.952..534154.573 rows=415224 loops=1)
估计行数:38。实际行数:超过 400K。有想法吗?
最佳答案
我的直接想法是,这可能与 work_mem 限制有关。计划之间的区别在于,在第一个计划中,您加入然后聚合,而在第二个计划中,您聚合并加入。这意味着您的聚合集更窄,这意味着该操作使用的内存更少。
如果您尝试将 work_mem 加倍并再次尝试,看看会发生什么变化会很有趣。
编辑:既然我们知道增加 work_mem 只会带来适度的改进,下一个问题是排序行估计。我怀疑它实际上超过了 work_mem 并且它期望这会很容易,因为它预计只有 38 行,但是却得到了很多行。我不清楚规划器是从哪里获得这些信息的,因为很明显规划器估计(正确地)38 行是我们期望从聚合中得到的行数。这部分对我来说开始看起来像是一个计划程序错误,但我很难把我的手指放在上面。可能值得在 pgsql-general 电子邮件列表中撰写和提出。在我看来,规划者几乎混淆了排序所需的内存和聚合所需的内存。
关于performance - 直接查询比使用 join 的子查询慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15126996/
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 8年前关闭。 Improve t
暂时忘记能力的定义,只关注能力的“检查”(使用“授权!”),我看到 CanCan 添加了大约 400 毫秒,用于简单地检查用户是否具有特定的能力主题/模型。 这是预期的吗(我假设不是)?或者,有没有可
我正在阅读有关 Swift 的教程 ( http://www.raywenderlich.com/74438/swift-tutorial-a-quick-start ),它预定义为不显式设置类型,因
这主要是由于对 SQL 问题的回答。由于性能原因,有意省略了 UDF 和子查询。我没有包括可靠性并不是说它应该被视为理所当然,但代码必须工作。 性能永远是第一位的吗?提供了许多以性能为主要优先事项的答
我已经编写了一个简单的测试平台来测量三种阶乘实现的性能:基于循环的,非尾递归的和尾递归的。 Surprisingly to me the worst performant was the loop o
我已将 ui-performance 插件应用到我的应用程序中。不幸的是,在开发模式下运行应用程序时它似乎不起作用。例如,我的 javascript 导入是用“vnull”版本呈现的。 例如 不会
我有一个我操作的 F# 引用(我在各处添加对象池以回收经常创建和删除的短期对象)。我想运行结果报价;现在我使用了 F# PowerPack,它提供了将引用转换为表达式树和委托(delegate)的方法
我正在尝试在 Spark 服务器上运行 SparklyR 库中的机器学习算法。 1 个簇 8 核 24G内存 Ubuntu 16.04 星火2.2 独立配置 1名师傅/2名 worker 每个执行器的
我有一个数据库(准确地说是在 postgres 上运行),具有以下结构: user1 (schema) | - cars (table) - airplanes (table, again) .
我的应用程序在我的 iPad 上运行。但它的表现非常糟糕——我的速度低于 15fps。谁能帮我优化一下? 它基本上是一个轮子(派生自 UIView),包含 12 个按钮(派生自 UIControl)。
在完成“Scala 中的函数式编程原则”@coursera 类(class)第 3 周的作业时,我发现当我实现视频类(class)中所示的函数联合时: override def union(tha
我正在重构我的一个 Controller 以使其成为一项服务,我想知道不将整个服务容器注入(inject)我的 Controller 是否会对性能产生影响。 这样效率更高吗: innova.path.
我有一个要显示的内容很大的文件。例如在显示用户配置文件时, 中的每个 EL 表达式需要一个 userId 作为 bean 的参数,该参数取自 session 上下文。我在 xhtml 文件中将这个 u
我非常了解 mipmapping。我不明白(在硬件/驱动程序级别)是 mipmapping 如何提高应用程序的性能(至少这是经常声称的)。在执行片段着色器之前,驱动程序不知道要访问哪个 mipmap
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: What's the (hidden) cost of lazy val? (Scala) Scala 允许定义惰
一些文章建议现在 build() 包含在 perform() 本身中,而其他人则建议当要链接多个操作时使用 build().perform()一起。 最佳答案 build() 包含在 perform(
Postgres docs说 For best optimization results, you should label your functions with the strictest vol
阅读Zero-cost abstractions看着 Introduction to rust: a low-level language with high-level abstractions我尝
我想在 MQ 服务器上部署 SSL,但我想知道我当前的 CPU 容量是否支持 SSL。 (我没有预算增加 CPU 内核和 MQ PVU 的数量) 我的规范: Windows 2003 服务器 SP2,
因此,我在 Chrome 开发者工具 的性能 选项卡内的时间 部分成功地监控了我的 React Native 应用程序的性能。 突然在应用程序的特定重新加载时,Timings 标签丢失。 我已尝试重置
我是一名优秀的程序员,十分优秀!