加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 更快速搜索字段的第1个字符与[A-Za-z]不匹配的

发布时间:2020-12-17 03:15:00 所属栏目:百科 来源:网络整理
导读:我目前有以下内容: User (id,fname,lname,deleted_at,guest) 我可以通过fname初始查询用户列表,如下所示: User Load (9.6ms) SELECT "users".* FROM "users" WHERE (users.deleted_at IS NULL) AND (lower(left(fname,1)) = 's') ORDER BY fname ASC LIMIT
我目前有以下内容:

User (id,fname,lname,deleted_at,guest)

我可以通过fname初始查询用户列表,如下所示:

User Load (9.6ms)  SELECT "users".* FROM "users" WHERE (users.deleted_at IS NULL) AND (lower(left(fname,1)) = 's') ORDER BY fname ASC LIMIT 25 OFFSET 0

由于以下索引,这很快:

CREATE INDEX users_multi_idx
  ON users (lower(left(fname,1)),fname)
  WHERE deleted_at IS NULL;

我现在想要做的是能够查询所有不以字母A-Z开头的用户.我这样做是这样的:

SELECT "users".* FROM "users" WHERE (users.deleted_at IS NULL) AND (lower(left(fname,1)) ~ E'^[^a-zA-Z].*') ORDER BY fname ASC LIMIT 25 OFFSET 0

但问题是这个查询非常慢并且似乎没有使用索引来加速第一个查询.关于如何优雅地使第二个查询(非a-z)更快的任何建议?

我正在使用带有rails 3.2的Postgres 9.1

谢谢

解决方法

更新的答案
Preceding question here.

我的第一个想法(索引与text_pattern_ops)在我的测试中不适用于正则表达式.更好地将您的查询重写为:

SELECT *
FROM   users
WHERE  deleted_at IS NULL
WHERE lower(left(fname,1)) < 'a' COLLATE "C" OR lower(left(fname,1)) > 'z' COLLATE "C"
ORDER  BY fname
LIMIT  25 OFFSET 0;

除了这些表达式通常更快之外,您的正则表达式中也包含大写字母,这与使用lower()的索引不匹配.与单个字符相比,尾随字符毫无意义.

并使用此索引:

CREATE INDEX users_multi_idx
ON users (lower(left(fname,1)) COLLATE "C",fname)
WHERE deleted_at IS NULL;

COLLATE "C"部件是可选的,仅在性能上有很小的贡献.它的目的是将排序规则重置为默认的posix排序规则,它只使用字节顺序,通常更快.有用,无论如何整理规则都不相关.

如果使用它创建索引,则只有与排序规则匹配的查询才能使用它.因此,如果性能不是您的首要要求,您可以跳过它来简化操作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读