Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 使用';类似于';_Performance_Postgresql_Indexing - Fatal编程技术网

Performance 使用';类似于';

Performance 使用';类似于';,performance,postgresql,indexing,Performance,Postgresql,Indexing,我需要根据特定列中的特定值从表中检索特定行,该列在示例中命名为columnX: select * from tableName where columnX similar to ('%A%|%B%|%C%|%1%|%2%|%3%') 因此,如果columnX至少包含一个指定的值(A、B、C、1、2、3),我将保留该行 我找不到比使用类似于的更好的方法。问题是,对于一个行数超过一百万的表来说,查询时间太长 我试着为它建立索引: create index tableName_columnX_id

我需要根据特定列中的特定值从表中检索特定行,该列在示例中命名为columnX

select *
from tableName 
where columnX similar to ('%A%|%B%|%C%|%1%|%2%|%3%')
因此,如果columnX至少包含一个指定的值(A、B、C、1、2、3),我将保留该行

我找不到比使用类似于的更好的方法。问题是,对于一个行数超过一百万的表来说,查询时间太长

我试着为它建立索引:

create index tableName_columnX_idx on tableName (columnX) 
where columnX similar to ('%A%|%B%|%C%|%1%|%2%|%3%')
但是,如果条件是可变的(值可以不是A、B、C、1、2、3),我需要为每个条件使用不同的索引

这个问题有没有更好的解决办法


编辑:谢谢大家的反馈。看来我达到这一点可能是因为一个设计错误(我在a中发布的主题)。

我将发布这篇文章作为一个答案,因为它可能会在将来指导其他人:为什么不有6个栏,
haveA
haveB
~
have3
和做一个6部分的
查询?还是使用位掩码

如果属性太多,无法为每个属性分配一列,我可能会尝试创建一个“属性”表:


让DBMS来考虑优化问题。

如果只搜索一个字符值的列表,则将每个字符串拆分为一个字符数组,并为数组编制索引:

CREATE INDEX
        ix_tablename_columnxlist
ON      tableName
USING   GIN((REGEXP_SPLIT_TO_ARRAY(columnX, '')))
然后根据索引进行搜索:

SELECT  *
FROM    tableName
WHERE   REGEXP_SPLIT_TO_ARRAY(columnX, '') && ARRAY['A', 'B', 'C', '1', '2', '3']
我同意@Quassnoi,a是最快和最简单的-除非写入性能或磁盘空间是问题,因为它占用了大量空间,并消耗了
插入
更新
删除
的大量性能

我的补充回答是由你的陈述引发的:

I can't find a better approach than using similar to.
如果这就是你发现的,那么你的搜索还没有结束<代码>类似于完全是浪费时间。字面上PostgreSQL的特点是符合(奇怪的)SQL标准。检查查询的
EXPLAIN ANALYZE
输出,您会发现类似于
已被正则表达式替换

在内部,每个类似于
表达式的
都被重写为正则表达式。因此,对于每个类似于
表达式的
,至少有一个正则表达式匹配要快一点。如果您不确定,让
解释分析
为您翻译。您在手册中找不到这一点,PostgreSQL不承诺这样做,但我还没有看到例外


更多细节。

这是一个数据建模问题。您似乎将
文本
字段用作一个集合,存储单字符代码以识别集合中存在的值

如果是这样,我希望使用以下方法之一重新构建此表:

  • 标准关系规范化。删除
    columnX
    ,并将其替换为一个新表,该表具有对
    tableName(id)
    的外键引用,以及一个
    charcode
    列,该列每行包含一个来自旧
    columnX
    的字符,如
    CREATE table tableName\u columnX\u set(tableName\u id integer非空引用tableName(id),charcode“char”,主键(tablename\u id,charcode))
    。然后,您可以使用普通的SQL子查询、联接等相当有效地搜索
    columnX
    中的键。如果您的应用程序无法处理该更改,您可以始终保留
    columnX
    ,并使用触发器维护边表

  • columnX
    转换为具有伪值的键的
    hstore
    。然后可以使用诸如
    columnX?| ARRAY['A','B','C']
    之类的hstore运算符。
    columnX
    的hstore上的
    GiST
    索引应该为这些操作提供相当可靠的性能

  • 如果您的表更改率较低,并且您可以支付GIN索引的费用,则拆分为一个数组

  • columnX
    转换为整数数组,使用
    intarray
    和intarray索引。在应用程序中具有代码到整数或转换的映射表


时间允许的话,我会跟进每一个的演示。生成虚拟数据是一件痛苦的事,因此它将取决于其他情况。

您是否总是要搜索单个字符值?类似于
'%ABC%|%BCD%'
的查询是否可能?是的,是基于单个字符的搜索。@FedericoCristina实际上,
columnX
是由
文本
字段中的单个字符代码表示的集合。对的这意味着
列X中的值顺序无关紧要。谢谢您的回答。也许我应该更好地解释这些值(A,B,C,1,2,3),其中仅用于示例。整套选项大约有24种。@FedericoCristina:更新了我的答案。我不确定最后一点是否正确。如果
columnX
具有值
ZAB
并且您正在搜索
A | B
,则该值不匹配,但应该匹配。哦,是的,抱歉。请将其归因于约40小时的失眠:)GIN索引维护起来可能非常昂贵,因此它并不特别适合插入/更新/删除率高的表。对于这个特殊的应用程序,这可能是问题,也可能不是问题。谢谢您的回答。不幸的是,这些表在不断变化(插入和更新)@FedericoCristina:不知道场景的详细信息,但是,在大多数情况下,频繁的完整扫描意味着服务器上的负载比索引更新(甚至
GIN
)要大。你真的试过这两种方法吗?同样,如果你考虑重新设计并能够安装扩展,你可以将你的标志存储在原生代码> iTalay中,并用更友好的更新代码<代码> GIST<代码>。看起来你对建模问题是正确的。我应该在那里做一些重构。我已经编辑了我的问题,并引用了一个新的领域特定问题。谢谢链接!你说得对
I can't find a better approach than using similar to.