PostgreSQL 标签系统 bit 位运算 查询性能

在标签系统中,通常会有多个属性,每个属性使用一个标签标示,最简单的标签是用0和1来表示,代表true和false。
我们可以把所有的标签转换成比特位,例如系统中一共有200个标签,5000万用户。
那么我们可以通过标签的位运算来圈定特定的人群。
这样就会涉及BIT位的运算。
那么我们来看看PostgreSQL位运算的性能如何?
PostgreSQL 9.5

postgres=# create table t_bit2 (id bit(200));
CREATE TABLE
Time: 1.018 ms
postgres=# insert into t_bit2 select B'10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010' from generate_series(1,50000000);
INSERT 0 50000000
Time: 47203.497 ms
postgres=# select count(*) from t_bit2 where bitand(id, '10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010')=B'10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010';
  count
----------
 50000000
(1 row)

Time: 14216.286 ms
postgres=# \dt+ t_bit2
                     List of relations
 Schema |  Name  | Type  |  Owner   |  Size   | Description
--------+--------+-------+----------+---------+-------------
 public | t_bit2 | table | postgres | 2873 MB |
(1 row)

PostgreSQL 9.6支持并行查询

postgres=#  create table t_bit2 (id bit(200));
CREATE TABLE
Time: 0.933 ms
postgres=# insert into t_bit2 select B'10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010' from generate_series(1,50000000);
INSERT 0 50000000
Time: 51485.962 ms
postgres=# explain (analyze,verbose,timing,costs,buffers) select count(*) from t_bit2 where bitand(id, '10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010')=B'10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010';
                                                                                                                                                                                                                                        QUERY
 PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Finalize Aggregate  (cost=471554.70..471554.71 rows=1 width=8) (actual time=9667.464..9667.465 rows=1 loops=1)
   Output: count(*)
   Buffers: shared hit=368140 dirtied=145199
   ->  Gather  (cost=471554.07..471554.68 rows=6 width=8) (actual time=9667.433..9667.454 rows=7 loops=1)
         Output: (PARTIAL count(*))
         Workers Planned: 6
         Workers Launched: 6
         Buffers: shared hit=368140 dirtied=145199
         ->  Partial Aggregate  (cost=470554.07..470554.08 rows=1 width=8) (actual time=9663.423..9663.424 rows=1 loops=7)
               Output: PARTIAL count(*)
               Buffers: shared hit=367648 dirtied=145199
               Worker 0: actual time=9662.545..9662.546 rows=1 loops=1
                 Buffers: shared hit=49944 dirtied=19645
               Worker 1: actual time=9661.922..9661.922 rows=1 loops=1
                 Buffers: shared hit=49405 dirtied=19198
               Worker 2: actual time=9662.924..9662.925 rows=1 loops=1
                 Buffers: shared hit=49968 dirtied=19641
               Worker 3: actual time=9662.483..9662.484 rows=1 loops=1
                 Buffers: shared hit=49301 dirtied=19403
               Worker 4: actual time=9663.341..9663.342 rows=1 loops=1
                 Buffers: shared hit=49825 dirtied=19814
               Worker 5: actual time=9663.605..9663.605 rows=1 loops=1
                 Buffers: shared hit=49791 dirtied=19586
               ->  Parallel Seq Scan on public.t_bit2  (cost=0.00..470468.39 rows=34274 width=0) (actual time=0.039..5724.642 rows=7142857 loops=7)
                     Output: id
                     Filter: (bitand(t_bit2.id, B'1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
0101010101010'::"bit") = B'10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010'::"bit")
                     Buffers: shared hit=367648 dirtied=145199
                     Worker 0: actual time=0.038..5676.776 rows=6792384 loops=1
                       Buffers: shared hit=49944 dirtied=19645
                     Worker 1: actual time=0.046..5675.846 rows=6719080 loops=1
                       Buffers: shared hit=49405 dirtied=19198
                     Worker 2: actual time=0.040..5678.657 rows=6795648 loops=1
                       Buffers: shared hit=49968 dirtied=19641
                     Worker 3: actual time=0.037..5678.587 rows=6704936 loops=1
                       Buffers: shared hit=49301 dirtied=19403
                     Worker 4: actual time=0.039..5667.813 rows=6776072 loops=1
                       Buffers: shared hit=49825 dirtied=19814
                     Worker 5: actual time=0.051..5677.367 rows=6771576 loops=1
                       Buffers: shared hit=49791 dirtied=19586
 Planning time: 0.100 ms
 Execution time: 9772.925 ms
(41 rows)
Time: 9773.874 ms
postgres=# select count(*) from t_bit2 where bitand(id, '10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010')=B'10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010';
  count
----------
 50000000
(1 row)
Time: 2326.541 ms

PostgreSQL 9.6的性能提升:

时间: 2024-08-30 04:56:34

PostgreSQL 标签系统 bit 位运算 查询性能的相关文章

PostgreSQL 百亿地理位置数据 近邻查询性能

背景 本文主要要展示的是PostgreSQL在位置信息近邻(KNN)查询方面的性能. 测试类型point,索引类型GiST. (PostGIS同样支持KNN查询,性能和本文的测试差不多)  测试数据量大于100亿. 结果 64个并发,随机选点,单次KNN查询请求的平均响应时间为0.848毫秒. 测试环境和优化请参考 http://blog.163.com/digoal@126/blog/static/16387704020160941345888/ 创建测试表 postgres=# create

性能优化-位运算效率高还是位运算效率高?

问题描述 位运算效率高还是位运算效率高? 在<java程序性能优化>中写到,位运算是运算中最高效的,而我依照书上的代码运行了一遍 发现并不是这样. 补上代码: public class BitOperate { public static void main(String[] args) { nomal(); bit(); } private static void nomal() { long start =System.currentTimeMillis(); long a = 100;

通过SQL Server的位运算功能巧妙解决多选查询方法_MsSql

无论使用int还是varchar,对于Status的多选查询都是不易应对的.举例,常规思维下对CustomerStatus的Enum设置如下: 复制代码 代码如下: [Serializable] public enum CustomerStatus { New = 0, Active = 1, Overdue = 2, Suspended = 3, Closing = 4, Closed = 5 } 在数据库中以int形式存储了Status值. 如果我在页面中想一次搜索状态为Active,Ove

通过SQL Server的位运算功能巧妙解决多选查询方法

无论使用int还是varchar,对于Status的多选查询都是不易应对的.举例,常规思维下对CustomerStatus的Enum设置如下: 复制代码 代码如下: [Serializable] public enum CustomerStatus { New = 0, Active = 1, Overdue = 2, Suspended = 3, Closing = 4, Closed = 5 } 在数据库中以int形式存储了Status值. 如果我在页面中想一次搜索状态为Active,Ove

提高DB2查询性能的常用方法

简介 随着DB2应用的逐渐增多,越来越多的数据库开发人员在项目开发过程中都会遇到查询过于复杂,导致性能难以接受的问题.本文将主要从一个数据库开发者的角度介绍几种常用的方法来提高 DB2 查询的性能,而并不讨论如何通过配置 DB2 的各项参数以及调整服务器环境等方式来提高整个数据库性能的方法.系统配置等工作属于 DBA 的工作范畴,在一般的项目开发中,这对于开发人员都是透明的.本文先对 DB2提供的几种用于提高查询性能的相关工具和命令进行介绍,然后根据笔者的工作经验介绍一些常用的技巧和方法来提高查

PostgreSQL 全表 全字段 模糊查询的毫秒级高效实现 - 搜索引擎也颤抖了

标签 PostgreSQL , 分词 , 全文检索 , 全字段检索 , 任意字段检索 , 下拉框选择 , 搜索引擎 背景 在一些应用程序中,可能需要对表的所有字段进行检索,有些字段可能需要精准查询,有些字段可能需要模糊查询或全文检索. 比如一些前端页面下拉框的勾选和选择. 这种需求对于应用开发人员来说,会很蛋疼,因为写SQL很麻烦,例子: 之前写过一篇文章来解决这个问题 <PostgreSQL 行级 全文检索> 使用的是全文检索,而当用户的需求为模糊查询时? 如何来解决呢? 不难想到我之前写过

Greenplum 点查(按PK查询)性能与提升空间

标签 PostgreSQL , Greenplum , 点查 , 按PK查询 背景 点查,基于PK的查询或者OLTP类查询,实际上并不是GPDB 擅长的,GPDB擅长的是海量的OLAP. 不过在企业.政府等窗口服务类业务,并发实际上并不高,如果GPDB的点查性能达到一定的性能时,实际上也能满足这类场景的需求. 测试 下面是一组测试,造10亿条测试数据,按PK查询. create table t_pk(id int primary key, info text, crt_time timestam

位运算小结操作

一.前言 输入2 的n 次方: 如果突然要你输入2 的19 次方,你是不是还要想一下呢?敲个524288 多累啊.用位运算:1 << 19 又快又准. 乘除2 的倍数: 千万不要用乘除法,非常拖效率.只要知道左移1 位就是乘以2 ,右移1 位就是除以2 就行了. 比如要算 25 * 4 ,用25 << 2 就好啦. 判断偶数:  a % 2 取模是最常用的判断方法之一.这样要用到除法运算,不好.实际上,还是用位运算解决:a & 1 .效果和a % 2 是一样的,但是要快得多

PHP位运算 详解

在实际应用中可以做用户权限的应用 我这里说到的权限管理办法是一个普遍采用的方法,主要是使用到"位运行符"操作,& 位与运算符. 位或运行符.参与运算的如果是10进制数,则会被转换至2进制数参与运算,然后计算结果会再转换为10进制数输出. 它的权限值是这样的 2^0=1,相应2进数为"0001″(在这里^我表示成"次方",即:2的0次方,下同) 2^1=2,相应2进数为"0010″ 2^2=4,相应2进数为"0100″ 2^3=8