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 usersWHERE deleted_at IS NulLWHERE lower(left(fname,1)) < 'a' ColLATE "C" OR lower(left(fname,1)) > 'z' ColLATE "C"ORDER BY fnameliMIT 25 OFFSET 0;
除了这些表达式通常更快之外,您的正则表达式中也包含大写字母,这与使用lower()的索引不匹配.与单个字符相比,尾随字符毫无意义.
并使用此索引:
CREATE INDEX users_multi_IDxON users (lower(left(fname,1)) ColLATE "C",fname)WHERE deleted_at IS NulL;
COLLATE "C"
部件是可选的,仅在性能上有很小的贡献.它的目的是将排序规则重置为默认的posix排序规则,它只使用字节顺序,通常更快.有用,无论如何整理规则都不相关.
如果使用它创建索引,则只有与排序规则匹配的查询才能使用它.因此,如果性能不是您的首要要求,您可以跳过它来简化 *** 作.
总结以上是内存溢出为你收集整理的ruby-on-rails – 更快速搜索字段的第1个字符与[A-Za-z]不匹配的记录?全部内容,希望文章能够帮你解决ruby-on-rails – 更快速搜索字段的第1个字符与[A-Za-z]不匹配的记录?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)