【问题标题】:Bitwise operations in PostgresPostgres 中的按位运算
【发布时间】:2012-02-11 03:42:13
【问题描述】:

我有以下表格:

types | id | name
------+----+----------
         1 | A
         2 | B
         4 | C
         8 | D
         16| E
         32| F

vendors | id | name     | type
--------+----+----------+-----
           1 | Alex     | 2     //type B only
           2 | Bob      | 5     //A,C
           3 | Cheryl   | 32    //F
           4 | David    | 43    //F,D,A,B
           5 | Ed       | 15    //A,B,C,D
           6 | Felix    | 8     //D
           7 | Gopal    | 4     //C
           8 | Herry    | 9     //A,D
           9 | Iris     | 7     //A,B,C
           10| Jack     | 23    //A,B,C,E

我现在想查询:

select id, name from vendors where type & 16 >0 //should return Jack as he is type E
select id, name from vendors where type & 7 >0 //should return Ed, Iris, Jack
select id, name from vendors where type & 8 >0 //should return David, Ed, Felix, Herry 

postgres 中表typesvendors 的最佳索引是什么?我可能在供应商中有数百万行。此外,与使用第三个表的多对多关系相比,使用这种按位方法的权衡是什么?哪个更好?

【问题讨论】:

  • 我认为你的意思是'type & 7 = 0',如果你使用'type & 7 >0',你将返回任何匹配'A'、'B'或'C'的项目,因为匹配任何位都会得到大于 0 的答案。(Alex、Bob、David、Ed、Goal、Henry、Iris、Jack)使“type & 7 = 0”只导致匹配所有三个位的那些项目。 (艾德、艾瑞斯、杰克)

标签: performance postgresql indexing bit-manipulation


【解决方案1】:

使用可以使用部分索引来解决“&”不是可索引运算符(afaik)的事实:

CREATE INDEX vendors_typeA ON vendors(id) WHERE (type & 2) > 0;
CREATE INDEX vendors_typeB ON vendors(id) WHERE (type & 4) > 0;

当然,每次添加新类型时都需要添加新索引。这是将数据扩展为关联表的原因之一,然后可以正确索引。您可以随时编写触发器来额外维护一个位掩码表,但使用多对多表来实际正常维护数据,因为它会更清晰。

如果您对扩展和性能的整个评估是说“我可能有数百万行”,那么您还没有做足够的工作来开始进行这种优化。首先创建一个结构合理的清晰模型,然后根据有关其性能的真实统计数据对其进行优化。

【讨论】:

    猜你喜欢
    • 2010-11-15
    • 2021-12-20
    • 2011-02-26
    • 2021-10-14
    • 2011-08-25
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多