Gan*_*row 1 postgresql performance index postgresql-performance
我有从用户到地址表的一对一关系。一位用户可以拥有一个搜索地址和一个经过验证的地址。
我在地址表上有两个索引:
我正在尝试仅为某些用户获取地址,而那些状态不是manual_verification
.
这是我的查询:
SELECT users.id
FROM "users" INNER JOIN addresses
ON addresses.user_id = users.id
and addresses.type = 'VerifiedAddress'
WHERE ("users".deleted_at IS NULL)
AND (users.id in (11144,10569,21519,783,15671,21726,17787,11665,
19579,12226,1324,9413,5461,20981,12906)
and addresses.state != 'manual_verification')
Run Code Online (Sandbox Code Playgroud)
解释上面的查询:http : //explain.depesz.com/s/rTj
需要 37 毫秒。有时更多取决于用户数量。
我认为这是一个很好的查询,但是我们的团队需要对此进行调查,我正在寻找一些优化技巧。我的意思是我做了一个字段选择,user_id(地址)和状态(地址)上有一个索引。
还有什么我可以做/尝试的吗?
更新
我发现这个查询的工作速度要快得多:
SELECT "addresses"."user_id"
FROM "addresses"
WHERE "addresses"."type" IN ('VerifiedAddress')
AND (user_id in (9681,23824,23760,20098,962,14730,12294,9552,534,
553,5837,6768,6583,956,24179) and state != 'manual_verification')
Run Code Online (Sandbox Code Playgroud)
解释这个查询:http : //explain.depesz.com/s/nHrr
我正在尝试仅为某些用户获取地址...
IN
不能很好地扩展大列表。将性能与unnest()
/JOIN
SELECT a.*
FROM unnest(ARRAY[9681,23824,23760,20098,962,14730,12294,9552,534,
553,5837,6768,6583,956,24179]) AS t(user_id)
JOIN addresses a USING (user_id)
WHERE a.type = 'VerifiedAddress'
AND a.state <> 'manual_verification'
Run Code Online (Sandbox Code Playgroud)
我希望state
并且type
至少是enum
类型。否则,您应该规范化您的数据库设计。有查找表state
,type
并且只使用一个小的 ID 引用那里的条目。使addresses
桌子更小,一切都更快。
假设所有列都NOT NULL
缺少信息。
如果您仍然需要更快的速度,并且如果有不止几行带有type <> 'VerifiedAddress'
or state = 'manual_verification'
,则部分索引会有所帮助。收益随着您可以从索引中排除的行的百分比而增长。
CREATE INDEX addresses_selection_idx ON addresses (user_id)
WHERE type = 'VerifiedAddress'
AND state <> 'manual_verification';
Run Code Online (Sandbox Code Playgroud)
确保WHERE
在查询中使用匹配条件以允许 Postgres 使用此索引。并权衡定制索引的好处与其成本(维护、额外磁盘空间、写入操作的小损失)。
归档时间: |
|
查看次数: |
248 次 |
最近记录: |