如何创建一个索引来加快表达式上的汇总查询?
-
16-10-2019 - |
题
我可能在标题中问了错误的问题。这是事实:
我的客户服务人员在我们基于Django网站的管理界面上进行客户查找时,一直抱怨响应时间缓慢。
我们正在使用Postgres 8.4.6。我开始记录缓慢的查询,发现了这个罪魁祸首:
SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')
此查询需要超过32秒的时间运行。这是解释提供的查询计划:
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)
因为这是Django Orm生成的查询,该查询是由Django Admin应用程序生成的Django Queryset生成的,所以我对查询本身没有任何控制权。索引似乎是逻辑解决方案。我尝试创建一个索引来加快这一速度,但没有区别:
CREATE INDEX auth_user_email_upper ON auth_user USING btree (upper(email::text))
我究竟做错了什么?我该如何加快此查询?
其他提示
该索引在比赛开始时的“%”是没有帮助的 - btree索引只能匹配前缀,而查询开始时的通配符意味着没有固定的前缀可以寻找。
这就是为什么它正在进行表扫描并依次与查询字符串相匹配的原因。
您可能需要查看使用全文索引和文本匹配运算符,而不是目前使用类似的子字符串搜索。您可以在文档中找到有关全文搜索的更多信息:
http://www.postgresql.org/docs/8.4/static/textsearch-intro.html
实际上,我从该页面上注意到,显然从来没有使用过索引,这对我来说似乎很奇怪,因为它应该能够使用BTREE索引来解决非Wildcard前缀。一些快速的测试表明,文档可能是正确的,但是在这种情况下,您在使用更喜欢解决查询时无需提供帮助。
不隶属于 dba.stackexchange