先决条件:文档资源(ER图)为here
您好,我在Refactory方面苦苦挣扎,搜索栏查询需要执行更复杂的操作。
最初,当您不是“ root”组的成员时,查询将在数据库中搜索“ users”,并且仅检索“ root”用户(只有2个组:root和non-roots。这代表了由名为“ root”的布尔列组成)。但是现在该平台需要支持更多角色,我这样定义它们:
例如: -如果用户已经附加了“ group_admin”角色和“ group1”角色,则该用户可以管理“ group1”角色成员的数据。 -如果用户已附加“ group2”角色,则该用户只能管理其数据。 -如果用户已附加了“ group-admin”,“ group1”和“ group2”角色,则他可以管理“ group1”和“ group2”成员的数据。 -如果用户具有“根”角色,则可以管理每个人的数据。
因此,正如您所看到的,用户管理的复杂性已经发生了很大变化。而且,重构也改变了数据模型和数据库实体。
正如我之前解释的,这些更改之一是用户搜索栏。 而且我认为该产品发布后,新查询的效果将不佳。
这是上一个查询:
EXPLAIN ANALYSE SELECT * FROM users
WHERE name ILIKE '%' || ? || '%'
AND root = true
这是新的查询:
EXPLAIN ANALYSE WITH selected AS (
SELECT DISTINCT group_enrollments.user_id, record_value
FROM group_enrollments, user_attributes
WHERE
user_attributes.user_id = group_enrollments.user_id AND
record_name = 'Name' AND
group_name = ? AND
record_value IN (
SELECT record_value
FROM group_enrollments, user_attributes
WHERE
user_attributes.user_id = group_enrollments.user_id AND
record_name = 'Name' AND
group_name = 'group_admin'
)
UNION ALL (
SELECT group_enrollments.user_id, record_value
FROM group_enrollments, user_attributes
WHERE user_attributes.user_id = group_enrollments.user_id AND
record_name = 'Name' AND
group_name = 'root'))
SELECT user_id, record_value
FROM selected
WHERE selected.record_value ILIKE '%' || ? || '%'
ORDER BY record_value ;
如您所见,查询增长了很多,而我对(查询计划程序的)长度和性能感到不满意
事实上。为了将AWS Cognito集成为身份提供商以增强安全性和合规性,也需要使用此重构。
以下是两者的查询计划:
Seq Scan on users (cost=0.00..2.56 rows=1 width=132) (actual time=0.016..0.023 rows=1 loops=1)
Filter: (root AND ((name)::text ~~* '%die%'::text))
Rows Removed by Filter: 49
Planning time: 0.136 ms
Execution time: 0.042 ms
Sort (cost=60.90..60.91 rows=2 width=14) (actual time=0.554..0.554 rows=2 loops=1)
Sort Key: user_attributes.record_value
Sort Method: quicksort Memory: 25kB
-> Append (cost=41.94..60.89 rows=2 width=14) (actual time=0.244..0.539 rows=2 loops=1)
-> Unique (cost=41.94..41.95 rows=1 width=14) (actual time=0.243..0.243 rows=1 loops=1)
-> Sort (cost=41.94..41.95 rows=1 width=14) (actual time=0.242..0.242 rows=1 loops=1)
Sort Key: user_attributes.record_value
Sort Method: quicksort Memory: 25kB
-> Nested Loop (cost=26.42..41.93 rows=1 width=14) (actual time=0.224..0.231 rows=1 loops=1)
-> Hash Semi Join (cost=26.27..36.25 rows=5 width=22) (actual time=0.153..0.210 rows=2 loops=1)
Hash Cond: (user_attributes.record_value = user_attributes_1.record_value)
-> Seq Scan on user_attributes (cost=0.00..9.79 rows=50 width=22) (actual time=0.015..0.054 rows=50 loops=1)
Filter: ((record_name)::text = 'Name'::text)
Rows Removed by Filter: 333
-> Hash (cost=26.26..26.26 rows=1 width=14) (actual time=0.118..0.118 rows=2 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Hash Join (cost=16.27..26.26 rows=1 width=14) (actual time=0.048..0.112 rows=2 loops=1)
Hash Cond: (user_attributes_1.user_id = group_enrollments_1.user_id)
-> Seq Scan on user_attributes user_attributes_1 (cost=0.00..9.79 rows=50 width=22) (actual time=0.004..0.067 rows=50 loops=1)
Filter: ((record_name)::text = 'Name'::text)
Rows Removed by Filter: 333
-> Hash (cost=16.25..16.25 rows=2 width=8) (actual time=0.013..0.013 rows=2 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Seq Scan on group_enrollments group_enrollments_1 (cost=0.00..16.25 rows=2 width=8) (actual time=0.007..0.010 rows=2 loops=1)
Filter: ((group_name)::text = 'group_admin'::text)
Rows Removed by Filter: 3
-> Index Only Scan using group_enrollment_user_id_group_name_uindex on group_enrollments (cost=0.15..1.13 rows=1 width=8) (actual time=0.007..0.007 rows=0 loops=2)
Index Cond: ((user_id = user_attributes.user_id) AND (group_name = 'b-sanus'::text))
Heap Fetches: 1
-> Nested Loop (cost=0.15..18.92 rows=1 width=14) (actual time=0.018..0.292 rows=1 loops=1)
-> Seq Scan on user_attributes user_attributes_2 (cost=0.00..10.75 rows=1 width=22) (actual time=0.011..0.282 rows=2 loops=1)
Filter: ((record_value ~~* '%die%'::text) AND ((record_name)::text = 'name'::text))
Rows Removed by Filter: 381
-> Index Only Scan using group_enrollment_user_id_group_name_uindex on group_enrollments group_enrollments_2 (cost=0.15..8.17 rows=1 width=8) (actual time=0.002..0.002 rows=0 loops=2)
Index Cond: ((user_id = user_attributes_2.user_id) AND (group_name = 'root'::text))
Heap Fetches: 1
Planning time: 0.647 ms
Execution time: 0.628 ms