imcs简介
https://github.com/knizhnik/imcs
翻译过来是在内存上的列存储,在对于一张‘静态’的表计算方面很有优势,在许多聚合运算中都有使用线程并行计算,而且其中使用了迭代器来对数据进行tile分割,数据存储在pg的共享内存中,在启动多个session都能够对这块内存进行操作,提高了查询效率。
imcs安装
第一步:修改Makefile或者将imcs目录拷贝到/postgres/contrib/目录下
vim Makefile
1 #ifdef USE_PGXS 2 PG_CONFIG = /usr/local/postgres/bin/pg_config //pg的安装目录 3 PGXS := $(shell $(PG_CONFIG) --pgxs) 4 include $(PGXS) 5 #else 6 #subdir = contrib/imcs 7 #top_builddir = ../.. 8 #include $(top_builddir)/src/Makefile.global 9 #include $(top_srcdir)/contrib/contrib-global.mk 10 #endif 11 12 [root@centos01 imcs]# make && make install
第二步:创建imcs扩展
1 postgres=# create extension imcs ; 2 3 postgres=# dx 4 List of installed extensions 5 Name | Version | Schema | Description 6 ---------+---------+------------+------------------------------ 7 imcs | 1.1 | public | In-Memory Columnar Store 8 9 postgres=# CREATE TABLE customer 10 postgres-# ( 11 postgres(# customer_id TEXT, 12 postgres(# review_date DATE, 13 postgres(# review_rating INTEGER, 14 postgres(# review_votes INTEGER, 15 postgres(# review_helpful_votes INTEGER, 16 postgres(# product_id CHAR(10), 17 postgres(# product_title TEXT, 18 postgres(# product_sales_rank BIGINT, 19 postgres(# product_group TEXT, 20 postgres(# product_category TEXT, 21 postgres(# product_subcategory TEXT 22 postgres(# );
第三步:生成user define funtion来对表进行查询
postgres=# select cs_create('customer','review_date','product_id'); postgres=# select customer_load();
注意1:操作此步会有许多错误,如果没有在postgres.conf中配置,由于没有初始化imcs的hash_table的前提下,往共享内存上插入是段错误的,但是此处没有打印出报错信息。
配置项:shared_preload_libraries = 'imcs'
注意2:postgres=# select customer_load();
ERROR: NULL values are not supported by columnar store
CONTEXT: PL/pgSQL function customer_load(boolean,text) line 1 at RETURN
在load数据时是不支持NULL value,但是imcs提供了可配置的选项让0来替代null数据,但是这种替代是毫无意义的,很多计算都是不准确的。
配置项:imcs.substitute_nulls=1
注意3:由于imcs使用字典来存储字符串,因此在开辟hash的时候需要将字典指定大一些,才能够装下这些字典。
配置项:imcs.dictionary_size=100000
注意4:还有一个配置选项是关于多线程的,如果配置>=2,则都会启动多线程来对存储上的数据分割计算,最后merge产生结果
配置项:imcs.n_threads=4
postgres=# select customer_load();
customer_load
---------------
176773
此时已经将pg的一张表的数据全部load到共享内存上了,可以使用imcs提供的udf函数对共享内存进行查询了。
查询对比如下:
postgres=# select cs_sum(review_rating) from customer_get(); cs_sum -------- 536823 (1 row) Time: 16.420 ms postgres=# select sum(review_rating) from customer ; sum -------- 536823 (1 row) Time: 133.685 ms
对于大部分聚合运算通过imcs提供的udf函数查询都能够比正常sql对pg原生表查询速度快。
还需要注意
postgres=# insert into customer select * from customer limit 1; INSERT 0 1 Time: 12.974 ms postgres=# select cs_sum(review_rating) from customer_get(); cs_sum -------- 536823 postgres=# select sum(review_rating) from customer ; sum -------- 536827
由此可以得到结论:在insert、update、delete数据后需要重新load数据到共享内存。
优点:1、多线程并行计算
2、运算效率高
3、迭代器是个多叉树结构,能够对tile数据mapreduce。
缺点:1、在做增删改操作后需要重新load一遍数据,如果数据量大,就消耗的时间
2、不支持null数据
3、代码使用宏编写,不易看懂,很难进行二次开发