标签: pattern-matching

PostgreSQL 中 LIKE、SIMILAR TO 或正则表达式的模式匹配

我必须编写一个简单的查询,在其中查找以 B 或 D 开头的人名:

SELECT s.name 
FROM spelers s 
WHERE s.name LIKE 'B%' OR s.name LIKE 'D%'
ORDER BY 1
Run Code Online (Sandbox Code Playgroud)

我想知道是否有办法重写它以提高性能。所以我可以避免or和/或like

postgresql index regular-expression pattern-matching string-searching

123
推荐指数
3
解决办法
18万
查看次数

如何创建索引以加速对表达式的聚合 LIKE 查询?

我可能在标题中问错了问题。以下是事实:

在我们基于 Django 的站点的管理界面上进行客户查询时,我的客户服务人员一直抱怨响应速度慢。

我们使用的是 Postgres 8.4.6。我开始记录慢查询,并发现了这个罪魁祸首:

SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')
Run Code Online (Sandbox Code Playgroud)

此查询的运行时间超过 32 秒。下面是 EXPLAIN 提供的查询计划:

QUERY PLAN
Aggregate  (cost=205171.71..205171.72 rows=1 width=0)
  ->  Seq Scan on auth_user  (cost=0.00..205166.46 rows=2096 width=0)
        Filter: (upper((email)::text) ~~ '%DEYK%'::text)
Run Code Online (Sandbox Code Playgroud)

因为这是 Django ORM 从 Django Admin 应用程序生成的 Django QuerySet 生成的查询,所以我无法控制查询本身。索引似乎是合乎逻辑的解决方案。我尝试创建一个索引来加快速度,但没有任何区别:

CREATE INDEX auth_user_email_upper ON auth_user USING btree (upper(email::text))
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我怎样才能加快这个查询?

postgresql performance index pattern-matching postgresql-8.4

26
推荐指数
2
解决办法
2万
查看次数

LIKE 是如何实现的?

谁能解释一下 LIKE 运算符是如何在当前数据库系统(例如 MySQL 或 Postgres)中实现的?或者指出一些解释它的参考资料?

天真的方法是检查每条记录,在感兴趣的字段上执行正则表达式或部分字符串匹配,但我有一种感觉(希望)这些系统做一些更聪明的事情。

mysql postgresql performance full-text-search pattern-matching

24
推荐指数
3
解决办法
1万
查看次数

为什么要在文本列上索引 text_pattern_ops ?

今天七周内的七个数据库向我介绍了每个操作员的索引。

您可以通过创建text_pattern_ops运算符类索引来为匹配先前查询的模式索引字符串,只要值以小写形式索引即可。

CREATE INDEX moves_title_pattern ON movies (
    (lower(title) text_pattern_ops);
Run Code Online (Sandbox Code Playgroud)

我们使用 是text_pattern_ops因为标题是文本类型。如果需要指数VARCHAR处理,字符,或名称,使用相关的OPS: ,varchar_pattern_opsbpchar_pattern_opsname_pattern_ops

我觉得这个例子真的很混乱。为什么这样做有用?

如果该列是文本类型,那么在用作搜索值之前,其他类型(varchar、char、name)不会被强制转换为文本吗?

该索引的行为与使用默认运算符的索引有何不同?

CREATE INDEX moves_title_pattern ON movies (lower(title));
Run Code Online (Sandbox Code Playgroud)

postgresql index collation pattern-matching

23
推荐指数
1
解决办法
2万
查看次数

随着搜索字符串变长,Trigram 搜索变得更慢

在 Postgres 9.1 数据库中,我有一个table1包含约 1.5M 行和一列的表label(为了这个问题而简化了名称)。

上有一个功能性的三元组索引lower(unaccent(label))(unaccent()已被设为不可变以允许其在索引中使用)。

以下查询非常快:

SELECT count(*) FROM table1
WHERE (lower(unaccent(label)) like lower(unaccent('%someword%')));
 count 
-------
     1
(1 row)

Time: 394,295 ms
Run Code Online (Sandbox Code Playgroud)

但以下查询速度较慢:

SELECT count(*) FROM table1
WHERE (lower(unaccent(label)) like lower(unaccent('%someword and some more%')));
 count 
-------
     1
(1 row)

Time: 1405,749 ms
Run Code Online (Sandbox Code Playgroud)

添加更多单词甚至更慢,即使搜索更严格。

我尝试了一个简单的技巧来运行第一个单词的子查询,然后使用完整的搜索字符串进行查询,但是(可悲的是)查询计划员看穿了我的阴谋:

EXPLAIN ANALYZE
SELECT * FROM (
   SELECT id, title, label from table1
   WHERE lower(unaccent(label)) like lower(unaccent('%someword%'))
   ) t1
WHERE lower(unaccent(label)) like lower(unaccent('%someword and some more%'));
Run Code Online (Sandbox Code Playgroud)
表1上的位图堆扫描(成本=16216.01..16220.04行=1宽度=212)(实际时间=1824.017..1824.019行=1循环=1) …

postgresql full-text-search pattern-matching postgresql-9.1 postgresql-9.4

17
推荐指数
1
解决办法
2106
查看次数

从 GIN 索引的 TSVECTOR 列获取部分匹配

我想通过查询得到结果:

SELECT * FROM (
  SELECT id, subject
  FROM mailboxes
  WHERE tsv @@ plainto_tsquery('avail')
) AS t1 ORDER by id DESC;
Run Code Online (Sandbox Code Playgroud)

这有效并返回tsv包含包含的行Available。但是如果我使用avai(dropped lable) 它找不到任何东西。

所有查询都必须在字典中吗?我们不能只查询这样的字母吗?我有一个包含电子邮件正文(内容)的数据库,我希望随着它每秒增长而使其快速增长。目前我正在使用

... WHERE content ~* 'letters`
Run Code Online (Sandbox Code Playgroud)

postgresql full-text-search pattern-matching

17
推荐指数
1
解决办法
2万
查看次数

PostgreSQL LIKE 对 ARRAY 字段的查询

有没有办法LIKE在 ARRAY 字段上进行Postgres查询?

目前我想要这样的东西:

SELECT * FROM list WHERE lower(array_field) LIKE '1234%'
Run Code Online (Sandbox Code Playgroud)

目前不需要那么多。但是它应该在 ARRAY 中找到一个匹配的字段。这甚至可能吗?

目前我使用物化视图来生成带有 JOIN 和 a 的“列表”表ARRAY_AGG(),因为我加入了一个表,其中更多的值可能在正确的表上。这会重复左表中的字段,这不是我想要的。

编辑这就是我创建视图的方式(非常缓慢和丑陋):

CREATE MATERIALIZED VIEW article_list_new AS
SELECT a.id, 
       a.oa_nr, 
       a.date_deleted, 
       a.lock, 
       a.sds_nr, 
       a.kd_art_nr, 
       a.kd_art_index, 
       a.kd_art_extend, 
       a.surface, 
       a.execution, 
       a.surface_area, 
       a.cu_thickness, 
       a.endintensity, 
       a.drilling, 
       array_agg(o.id::text) AS offer_list 
FROM article_list a LEFT JOIN task_offer o ON o.article = a.oa_nr 
GROUP BY .....;  
Run Code Online (Sandbox Code Playgroud)

我还需要返回task_offer表的 ID 。

postgresql database-design pattern-matching

13
推荐指数
1
解决办法
2万
查看次数

如何在 PostgreSQL 全文搜索中搜索带连字符的单词?

我必须搜索带连字符的单词,例如“早安”、“晚安”等。

我的查询是:

select id, ts_headline(content,
                       to_tsquery('english','good-morning'),
                       'HighlightAll=true MaxFragments=100 FragmentDelimiter=$') 
from table 
where ts_content @@ to_tsquery('english','good-morning');
Run Code Online (Sandbox Code Playgroud)

执行此查询时,我还会分别获得“good”“morning”的结果。但我想要完全匹配的单词和片段。
(因为ts_content我使用相同的默认配置english来创建tsvector.)

如何在 PostgreSQL 全文搜索中搜索此类带连字符的单词?

postgresql full-text-search pattern-matching

12
推荐指数
1
解决办法
4639
查看次数

寻找最长前缀的算法

我有两张桌子。

第一个是带前缀的表

code name price
343  ek1   10
3435 nt     4
3432 ek2    2
Run Code Online (Sandbox Code Playgroud)

二是带有电话号码的通话记录

number        time
834353212     10
834321242     20
834312345     30
Run Code Online (Sandbox Code Playgroud)

我需要编写一个脚本,从每条记录的前缀中找到最长的前缀,并将所有这些数据写入第三个表,如下所示:

 number        code   ....
 834353212     3435
 834321242     3432
 834312345     343
Run Code Online (Sandbox Code Playgroud)

对于数字 834353212,我们必须修剪 '8',然后从前缀表中找到最长的代码,即 3435。
我们必须始终先删除 '8',并且前缀必须在开头。

我很久以前以非常糟糕的方式解决了这个任务。它是糟糕的 perl 脚本,它对每条记录进行大量查询。这个脚本:

  1. 从调用表中取一个数字,在循环中从 length(number) 到 1 => $prefix 做子串

  2. 执行查询: select count(*) from prefixes where code like '$prefix'

  3. 如果计数> 0,则取第一个前缀并写入表

第一个问题是查询计数 - 它是call_records * length(number). 第二个问题是LIKE表达。恐怕那些很慢。

我试图通过以下方式解决第二个问题:

CREATE EXTENSION pg_trgm;
CREATE INDEX prefix_idx ON prefix USING …
Run Code Online (Sandbox Code Playgroud)

postgresql performance pattern-matching postgresql-9.1 query-performance

11
推荐指数
1
解决办法
8904
查看次数

相似度函数的最佳索引

所以我有这个包含 620 万条记录的表,我必须对列执行具有相似性的搜索查询。查询可以是:

 SELECT  "lca_test".* FROM "lca_test"
 WHERE (similarity(job_title, 'sales executive') > 0.6)
 AND worksite_city = 'los angeles' 
 ORDER BY salary ASC LIMIT 50 OFFSET 0
Run Code Online (Sandbox Code Playgroud)

可以在 where(year = X, worksite_state = N, status = 'certified',visa_class = Z) 中添加更多条件。

运行其中一些查询可能需要很长时间,超过 30 秒。有时超过一分钟。

EXPLAIN ANALYZE 前面提到的查询给了我这个:

Limit  (cost=0.43..42523.04 rows=50 width=254) (actual time=9070.268..33487.734 rows=2 loops=1)
->  Index Scan using index_lca_test_on_salary on lca_test  (cost=0.43..23922368.16 rows=28129 width=254) (actual time=9070.265..33487.727 rows=2 loops=1)
>>>> Filter: (((worksite_city)::text = 'los angeles'::text) AND (similarity((job_title)::text, 'sales executive'::text) > 0.6::double precision)) …
Run Code Online (Sandbox Code Playgroud)

postgresql index full-text-search pattern-matching postgresql-9.3

11
推荐指数
1
解决办法
8946
查看次数