我可能在标题中问错了问题。以下是事实:
在我们基于 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
DyanmoDB最佳实践明确指出:
您应该在 DynamoDB 应用程序中维护尽可能少的表。大多数设计良好的应用程序只需要一张表。
我觉得很有趣,我见过的处理 DyanmoDB 的几乎每个教程都有多表设计。
但这在实践中意味着什么?
让我们考虑一个具有三个主要实体的简单应用程序:用户、项目和文档。一个用户拥有多个项目,一个项目可以有多个文档。我们通常必须查询用户的项目和项目的文档。读取数量大大超过写入数量。
一个天真的教程的表格设计将使用三个表格:
Users
Hash key
user-id
Projects
Hash key Global Index
project-id user-id
Documents
Hash key Global Index
document-id project-id
Run Code Online (Sandbox Code Playgroud)
我们可以很容易崩溃Project,并Document为一个Documents表:
Documents
Hash key Sort key Global Index
project-id document-id user-id
Run Code Online (Sandbox Code Playgroud)
但为什么要停在那里?为什么不用一张桌子来统治他们呢?既然User是一切的根源...
Users
Hash key Sort key
user-id aspect
--------- ---------
foo user email: foo@bar.com ...
foo project:1 title: "The Foo Project"
foo project:1:document:2 document-id: 2 ...
Run Code Online (Sandbox Code Playgroud)
然后我们将有一个全局索引,例如,email用于用户记录查找的document-id字段,以及另一个用于直接文档查找的字段。 …