我正在尝试优化以下查询,但我不清楚哪些索引或索引最好。我将瓷砖存储在二维平面中并查询该平面的矩形区域。出于本问题的目的,该表包含以下列:
我有以下索引:
这是我正在尝试优化的查询:
ywot=> EXPLAIN ANALYZE SELECT * FROM "ywot_tile" WHERE ("world_id" = 27685 AND "tileY" <= 6 AND "tileX" <= 9 AND "tileX" >= -2 AND "tileY" >= -1 ); QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on ywot_tile (cost=11384.13..149421.27 rows=65989 width=168) (actual time=79.646..80.075 rows=96 loops=1)
Recheck Cond: ((world_id = 27685) AND ("tileY" <= 6) AND ("tileY" >= (-1)) AND ("tileX" <= 9) AND ("tileX" >= (-2)))
-> Bitmap Index Scan on ywot_tile_world_id_key (cost=0.00..11367.63 rows=65989 width=0) (actual time=79.615..79.615 rows=125 loops=1)
Index Cond: ((world_id = 27685) AND ("tileY" <= 6) AND ("tileY" >= (-1)) AND ("tileX" <= 9) AND ("tileX" >= (-2)))
Total runtime: 80.194 ms
所以世界是固定的,我们正在寻找一个矩形的瓷砖区域。可能相关的更多信息:
我唯一能想到的就是索引(世界,X)和(世界,Y)。我的猜测是,数据库可以采用这两组并将它们相交。问题是,对于其中任何一个,都存在潜在的无限数量的匹配。是否有其他类型的指数更合适?
答案 0 :(得分:2)
将表格集中在“ywot_tile_world_id_key”上,主键似乎只是一个人工id。如果您有更多唯一的垂直值,而不是水平值,则可能需要反转顺序(world-id,y,x)。同时删除world-id上的唯一索引,它由复合索引复制。
答案 1 :(得分:1)
X,Y的GIST与PostGIS的GIST非常相似。事实上,您甚至可以使用Postgresql的PostGIS扩展程序并获得相当大的收益
答案 2 :(得分:0)
这就是我最终做的事情。查询现在大约是20ms而不是80,这是一个不错的改进,虽然并不令人惊讶。
CREATE INDEX CONCURRENTLY ywot_tile_boxes ON ywot_tile USING gist (world_id, box(point("tileX","tileY"),point("tileX","tileY")));
SELECT * FROM "ywot_tile" WHERE world_id = 27685 AND box(point("tileX","tileY"),point("tileX","tileY")) && box(point(-2,-1),point(9,6));
非常感谢任何进一步的建议。