Dr.*_*YSG 14 postgresql postgis
我有一个有 50K 行的表。它实际上是一个 PostGIS 表。
查询有 4 个部分(1 个强制)(3 个可选)
我预计大约有 100 - 4,000 行返回
如果我在表上创建复合索引,我应该先使用哪一列。细粒度的可能是位置(数据分布在世界各地)。我目前将其作为 GIST 索引。
其他索引将是 BTREE。
我的直觉是使用细粒度的,当然最后。例如,只有大约 12 种文件类型,因此对于索引来说这将是非常大的存储桶。
PostgreSQL 和 PostGIS 大师(了解系统内部结构的人)怎么说?
更新:
让我尖锐地回答这个问题。
请告诉我这些假设是否有误。(我对复合索引的想法很陌生)
再说一次,我不是要求任何人设计我的解决方案,我也不会胡思乱想其他人的工作。但我确实需要 PostGreSQL 文档没有告诉我有关实现的东西
[我还没有 EXPLAIN 结果显示的原因是我必须从 24M 行表创建这个 25K 行表。这比我想象的要花费更多的时间。我将事物聚类为 1,000 个项目组,并让用户查询 25K 行表。但我的下一个问题,将涉及使用该查询的结果转到 MASTER 25M 行表并将其提取出来,这就是复合索引的性能真正发挥作用的地方]。
示例查询如下:
SELECT
public.product_list_meta_mv.cntry_name AS country,
public.product_list_meta_mv.product_producer AS producer,
public.product_list_meta_mv.product_name AS prod_name,
public.product_list_meta_mv.product_type AS ptype,
public.product_list_meta_mv.product_size AS size,
ST_AsGeoJSON(public.product_list_meta_mv.the_geom, 10, 2) AS outline
FROM
public.product_list_meta_mv
WHERE
public.product_list_meta_mv.cntry_name = 'Poland'
AND
ST_Intersects(public.product_list_meta_mv.the_geom,
st_geogfromtext('SRID=4326;POLYGON((21.23107910156250 51.41601562500000,
18.64379882812500 51.41601562500000,
18.64379882812500 48.69415283203130,
21.23107910156250 48.69415283203130,
21.23107910156250 51.41601562500000))'))
AND (date >= '1/2/1900 5:00:00 AM'
AND date <= '2/26/2014 10:26:44 PM')
AND (public.product_list_meta_mv.product_type in
('CIB10','DTED0','DTED1','DTED2','CIB01','CIB05')) ;
Run Code Online (Sandbox Code Playgroud)
EXPLAIN ANALYZE 结果(我没有输入任何复合索引,从我看到的速度来看,我不知道是否需要)。
"Bitmap Heap Scan on catalog_full cat (cost=4.33..37.49 rows=1 width=7428) (actual time=1.147..38.051 rows=35 loops=1)"
" Recheck Cond: ('0103000020E61000000100000005000000000000005838354000000000AEB0494000000000A0A7324000000000AEB0494000000000A0A73240000000006C5D48400000000058383540000000006C5D4840000000005838354000000000AEB04940'::geography && outline)"
" Filter: (((type)::text = ANY ('{CADRG,CIB10,DTED1,DTED2}'::text[])) AND (_st_distance('0103000020E61000000100000005000000000000005838354000000000AEB0494000000000A0A7324000000000AEB0494000000000A0A73240000000006C5D48400000000058383540000000006C5D4840000000005838354000000000AEB04940'::geography, outline, 0::double precision, false) < 1e-005::double precision))"
" Rows Removed by Filter: 61"
" -> Bitmap Index Scan on catalog_full_outline_idx (cost=0.00..4.33 rows=8 width=0) (actual time=0.401..0.401 rows=96 loops=1)"
" Index Cond: ('0103000020E61000000100000005000000000000005838354000000000AEB0494000000000A0A7324000000000AEB0494000000000A0A73240000000006C5D48400000000058383540000000006C5D4840000000005838354000000000AEB04940'::geography && outline)"
"Total runtime: 38.109 ms"
Run Code Online (Sandbox Code Playgroud)
EXPLAIN ANALYZE SELECT pid,product_name,type,country,date,size,cocom,description,egpl_date,ST_AsGeoJSON(outline, 10, 2) AS outline
FROM portal.catalog_full AS cat
WHERE ST_Intersects(st_geogfromtext('SRID=4326;POLYGON((21.2200927734375 51.38031005859375, 18.65478515625 51.38031005859375, 18.65478515625 48.7298583984375, 21.2200927734375 48.7298583984375, 21.2200927734375 51.38031005859375))'), cat.outline)
AND (cat.type in ('CADRG','CIB10','DTED1','DTED2'))
Run Code Online (Sandbox Code Playgroud)
小智 8
作为我工作的一部分,我维护了一个相当大的 PostgreSQL 数据库(磁盘上大约 120GB,几个数百万行的表)并收集了一些关于如何加快查询速度的技巧。首先对你的假设发表一些评论:
我建议不要制作 4 向索引。尝试创建一个然后检查大小,它们会变得非常大。根据我的经验,四个 1-key 索引几乎和单个 4-way 索引一样快。一个对某些特定查询效果很好的技巧是部分索引,即这样的东西:
CREATE INDEX ON table_x (key1, key2, key3) WHERE some_x_column = 'XXXX';
我在我的 .psqlrc 文件中创建了别名,并带有查询以帮助查找要添加或删除的索引。请随意在 GitHub 上查看它们: .psql
我经常使用 :seq_scans 和 :bigtables,然后使用 \d table_name 来获取有关该表的详细信息。完成一些更改后不要忘记重置统计信息,选择 pg_stat_reset();