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. 我的第一个想法(索引与 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;
如果使用它创建索引,则只有与排序规则匹配的查询才能使用它.因此,如果性能不是您的首要要求,您可以跳过它来简化操作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |