【发布时间】:2021-05-23 22:01:26
【问题描述】:
我们有一个包含数千万个多边形的表格,我们有这个索引:
CREATE INDEX IF NOT EXISTS polygons_geog_idx ON polygons USING GIST(geog);
这让我们可以真正高效地查询数据库,如下所示:
SELECT * FROM polygons WHERE st_dwithin('SRID=4326;POINT(-1 50)'::geography, geog, 500);
现在由于业务需求,我们只需要返回最大的 200 个多边形。很容易做到:
LIMIT 200ORDER BY st_area(geog)
完整查询:
SELECT gid, st_area(geog) as size FROM polygons WHERE st_dwithin(geog, 'SRID=4326;POINT(-1 50)'::geography, 500) ORDER BY st_area(geog) DESC LIMIT 200.
由于 order by 和 select 我们的查询速度减慢了 10 倍。我认为通过添加另一个索引(如SO Answer:CREATE INDEX polygons_geog_area_idx ON polygons (st_area(geog));
但是polygons_geog_area_idx好像没有被接:
Sort (cost=8.23..8.23 rows=1 width=12) (actual time=133.755..142.427 rows=2325 loops=1)
Sort Key: (st_area(geog, true))
Sort Method: quicksort Memory: 205kB
-> Index Scan using polygons_geog_idx on polygons (cost=0.14..8.22 rows=1 width=12) (actual time=0.468..121.974 rows=2325 loops=1)
Index Cond: (geog && '0101000020E6100000C33126587787F1BF3B0D62B197654940'::geography)
Filter: (('0101000020E6100000C33126587787F1BF3B0D62B197654940'::geography && _st_expand(geog, '500'::double precision)) AND _st_dwithin(geog, '0101000020E6100000C33126587787F1BF3B0D62B197654940'::geography, '500'::double precision, true))
Rows Removed by Filter: 3
Planning Time: 0.157 ms
Execution Time: 151.196 ms
(注意:这是在开发数据集上,比稍后运行的实际数据集要小得多)
我错过了什么?你甚至可以使用我想要的 2 个索引吗?
【问题讨论】:
-
请同时显示更快的计划。
-
@jjanes 更快的计划是什么意思?
-
没有顺序的那个要快 10 倍。 (但如果生成的列确实有效,它可能就不再重要了)
-
它确实有效@jjanes。谢谢你。我只是好奇为什么。
标签: postgresql performance indexing postgis