【发布时间】:2012-09-17 13:10:47
【问题描述】:
人物:
- id BIGINT
- geo_point 点 (PostGIS)
- stroke_when TIMESTAMPTZ(已编入索引!)
- stroke_when_second双精度
PostgeSQL 9.1、PostGIS 2.0。
1.查询:
SELECT ST_AsText(geo_point)
FROM lightnings
ORDER BY stroke_when DESC, stroke_when_second DESC
LIMIT 1
总运行时间:31100.911 毫秒!
解释(ANALYZE on、VERBOSE off、COSTS on、BUFFERS on):
Limit (cost=169529.67..169529.67 rows=1 width=144) (actual time=31100.869..31100.869 rows=1 loops=1)
Buffers: shared hit=3343 read=120342
-> Sort (cost=169529.67..176079.48 rows=2619924 width=144) (actual time=31100.865..31100.865 rows=1 loops=1)
Sort Key: stroke_when, stroke_when_second
Sort Method: top-N heapsort Memory: 17kB
Buffers: shared hit=3343 read=120342
-> Seq Scan on lightnings (cost=0.00..156430.05 rows=2619924 width=144) (actual time=1.589..29983.410 rows=2619924 loops=1)
Buffers: shared hit=3339 read=120342
2.选择另一个字段:
SELECT id
FROM lightnings
ORDER BY stroke_when DESC, stroke_when_second DESC
LIMIT 1
总运行时间:2144.057 毫秒。
解释(ANALYZE on、VERBOSE off、COSTS on、BUFFERS on):
Limit (cost=162979.86..162979.86 rows=1 width=24) (actual time=2144.013..2144.014 rows=1 loops=1)
Buffers: shared hit=3513 read=120172
-> Sort (cost=162979.86..169529.67 rows=2619924 width=24) (actual time=2144.011..2144.011 rows=1 loops=1)
Sort Key: stroke_when, stroke_when_second
Sort Method: top-N heapsort Memory: 17kB
Buffers: shared hit=3513 read=120172
-> Seq Scan on lightnings (cost=0.00..149880.24 rows=2619924 width=24) (actual time=0.056..1464.904 rows=2619924 loops=1)
Buffers: shared hit=3509 read=120172
3.正确优化:
SELECT id
FROM lightnings
ORDER BY stroke_when DESC
LIMIT 1
总运行时间:0.044 毫秒
解释(ANALYZE on、VERBOSE off、COSTS on、BUFFERS on):
Limit (cost=0.00..3.52 rows=1 width=16) (actual time=0.020..0.020 rows=1 loops=1)
Buffers: shared hit=5
-> Index Scan Backward using lightnings_idx on lightnings (cost=0.00..9233232.80 rows=2619924 width=16) (actual time=0.018..0.018 rows=1 loops=1)
Buffers: shared hit=5
如您所见,尽管当 SQL 优化器使用索引时查询是非常原始的,但存在两个糟糕且截然不同的冲突:
- 即使优化器不使用索引,为什么使用 As_Text(geo_point) 而不是 id 会花费更多时间?结果只有一行!
- 当 ORDER BY 中显示未索引的字段时,无法使用一阶索引。提到在实践中,DB 中每秒只显示几行。
当然,上面是一个简化的查询,是从一个更复杂的结构中提取的。通常我会按日期范围选择行,应用复杂的过滤器。
【问题讨论】:
-
如果您的实际案例比较复杂,您可能已经从展示案例中抽象出了真正的问题。
标签: postgresql