【原创】PostgreSQL hstore 列性能提升一例
发布时间:2020-12-13 17:29:01 所属栏目:百科 来源:网络整理
导读:PostgreSQL 支持hstore 来存放KEY-VALUE这类数据, 其实也类似于ARRAY或者JSON类型。 要高效的使用这类数据,当然离不开高效的索引。我们今天就来看看两类不同的索引对于同一种检索请求的性能问题。 假如我们有这样一个原始表,基于str1字段有一个BTREE索引
PostgreSQL 支持hstore 来存放KEY->VALUE这类数据, 其实也类似于ARRAY或者JSON类型。 要高效的使用这类数据,当然离不开高效的索引。我们今天就来看看两类不同的索引对于同一种检索请求的性能问题。 假如我们有这样一个原始表,基于str1字段有一个BTREE索引。 t_girl=#dstatus_check; Table"ytt.status_check" Column|Type|Modifiers --------+-----------------------+----------- is_yes|boolean|notnull str1|charactervarying(20)|notnull str2|charactervarying(20)|notnull Indexes: "index_status_check_str1"btree(str1) 里面有10W条记录。 数据大概如下, t_girl=#select*fromstatus_checklimit2; is_yes|str1|str2 --------+------+---------------------- f|0|cfcd208495d565ef66e7 t|1|c4ca4238a0b923820dcc (2rows) Time:0.617ms t_girl=# 存放hstore类型的status_check_hstore 表结构,基于str1_str2字段有一个GIST索引。 Table"ytt.status_check_hstore" Column|Type|Modifiers -----------+---------+----------- is_yes|boolean| str1_str2|hstore| Indexes: "idx_str_str2_gist"gist(str1_str2) t_girl=#select*fromstatus_check_hstorelimit2; is_yes|str1_str2 --------+----------------------------- f|"0"=>"cfcd208495d565ef66e7" t|"1"=>"c4ca4238a0b923820dcc" (2rows) Time:39.874ms 接下来我们要得到跟查询原始表一样的结果,当然原始表的查询非常高效。 表语句以及结果如下, t_girl=#select*fromstatus_checkwherestr1in('10','23','33'); is_yes|str1|str2 --------+------+---------------------- t|10|d3d9446802a44259755d t|23|37693cfc748049e45d87 f|33|182be0c5cdcd5072bb18 (3rows) Time:0.690ms 上面的语句用了不到1毫秒。 接下来我们对hstore表进行查询, t_girl=#selectis_yes,skeys(str1_str2),svals(str1_str2)fromstatus_check_hstorewherestr1_str2?|array['10','33']; is_yes|skeys|svals --------+-------+---------------------- t|10|d3d9446802a44259755d t|23|37693cfc748049e45d87 f|33|182be0c5cdcd5072bb18 (3rows) Time:40.256ms 我的天,比原始表的查询慢了几十倍。 看下查询计划,把所有行都扫描了一遍。 QUERYPLAN ----------------------------------------------------------------------------------- BitmapHeapScanonstatus_check_hstore(cost=5.06..790.12rows=100000width=38) RecheckCond:(str1_str2?|'{10,23,33}'::text[]) ->BitmapIndexScanonidx_str_str2_gist(cost=0.00..5.03rows=100width=0) IndexCond:(str1_str2?|'{10,33}'::text[]) (4rows) Time:0.688ms 我们想办法来优化这条语句, 如果把这条语句变成跟原始语句一样的话,那么是否就可以用到BTREE索引了? 接下来,建立一个基于BTREE的函数索引, t_girl=#createindexidx_str1_str2_akeysonstatus_check_hstoreusingbtree(array_to_string(akeys(str1_str2),',')); CREATEINDEX Time:394.123ms OK,变化语句来执行下同样的检索, t_girl=#selectis_yes,svals(str1_str2)fromstatus_check_hstorewherearray_to_string(akeys(str1_str2),')in('10','33'); is_yes|skeys|svals --------+-------+---------------------- t|10|d3d9446802a44259755d t|23|37693cfc748049e45d87 f|33|182be0c5cdcd5072bb18 (3rows) Time:0.727ms 这次和原始查询速度一样快了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |