こんにちは) django-pgcrypto-fields を使用した後、パフォーマンスの問題があります。
モデルは:
class AssignedEmployee(models.Model):
user_email = CharPGPSymmetricKeyField(max_length=50)
project = models.ForeignKey('Project', on_delete=models.CASCADE, db_index=True)
status_of_assignment = models.BooleanField(default=False, null=True)
datetime_of_assignment = DateTimePGPSymmetricKeyField(null=True)
exception_text = CharPGPSymmetricKeyField(max_length=255, null=True)
class Meta:
unique_together = (('user_email', 'project'), )
views.py: 1位:
def action_required_projects(request):
assigned_projects = AssignedEmployee.objects.filter(
user_email__iexact=request.user.email,
status_of_assignment=False).select_related('project').order_by('project_id')
2番目:
def signed_projects(request):
assigned_projects = AssignedEmployee.objects.filter(
user_email__iexact=request.user.email,
status_of_assignment=True).select_related('project').order_by('-project_id')
したがって、2 番目のビューは 18 倍遅くなります。status_of_assignment=True を status_of_assignment=False に変更すると、最初のものと同じくらい速く動作します。Explain() と print_sql は私にこれを示しています: 最初のビュー:
SELECT "assignedemployee"."id",
pgp_sym_decrypt("assignedemployee"."user_email", 'secret_key')::TEXT,
"assignedemployee"."project_id",
"assignedemployee"."status_of_assignment",
pgp_sym_decrypt("assignedemployee"."datetime_of_assignment", 'secret_key')::TIMESTAMP,
"project"."id",
pgp_sym_decrypt("project"."language", 'secret_key')::TEXT,
pgp_sym_decrypt("project"."client_name", 'secret_key')::TEXT,
pgp_sym_decrypt("project"."engagement_name", 'secret_key')::TEXT,
pgp_sym_decrypt("project"."deadline", 'secret_key')::DATE,
"project"."status",
pgp_sym_decrypt("project"."access", 'secret_key')::TEXT
FROM "assignedemployee"
INNER JOIN "project" ON ("assignedemployee"."project_id" = "project"."id")
WHERE ("assignedemployee"."status_of_assignment" = FALSE
AND UPPER(pgp_sym_decrypt("assignedemployee"."user_email", 'secret_key')::TEXT::text) = UPPER(Pavel@example.com))
ORDER BY "assignedemployee"."project_id" ASC
Sort (cost=238.09..238.10 rows=3 width=189) (actual time=226.059..226.059 rows=3 loops=1)
Sort Key: assignedemployee.project_id
Sort Method: quicksort Memory: 25kB
-> Nested Loop (cost=0.57..238.06 rows=3 width=189) (actual time=218.194..226.005 rows=3 loops=1)
-> Index Scan using assign_status__63421e_idx on assignedemployee (cost=0.29..213.08 rows=3 width=196) (actual time=215.875..219.181 rows=3 loops=1)
Index Cond: (status_of_assignment = false)
Filter: ((NOT status_of_assignment) AND (upper(pgp_sym_decrypt(user_email, 'secret_key'::text)) = 'PAVEL@example.COM'::text))
Rows Removed by Filter: 536
-> Index Scan using projec_id_dcb74d_idx on project (cost=0.28..8.30 rows=1 width=443) (actual time=0.010..0.010 rows=1 loops=3)
Index Cond: (id = assignedemployee.project_id)
Planning time: 1.842 ms
Execution time: 226.100 ms
そして2番目に
SELECT "assignedemployee"."id",
pgp_sym_decrypt("assignedemployee"."user_email", 'secret_key')::TEXT,
"assignedemployee"."project_id",
"assignedemployee"."status_of_assignment",
pgp_sym_decrypt("assignedemployee"."datetime_of_assignment", 'secret_key')::TIMESTAMP,
"project"."id",
pgp_sym_decrypt("project"."language", 'secret_key')::TEXT,
pgp_sym_decrypt("project"."client_name", 'secret_key')::TEXT,
pgp_sym_decrypt("project"."engagement_name", 'secret_key')::TEXT,
pgp_sym_decrypt("project"."deadline", 'secret_key')::DATE,
"project"."status",
pgp_sym_decrypt("project"."access", 'secret_key')::TEXT
FROM "assignedemployee"
INNER JOIN "project" ON ("assignedemployee"."project_id" = "project"."id")
WHERE ("assignedemployee"."status_of_assignment" = TRUE
AND UPPER(pgp_sym_decrypt("assignedemployee"."user_email", 'secret_key')::TEXT::text) = UPPER(Pavel@example.com))
ORDER BY "assignedemployee"."project_id" DESC
Sort (cost=1988.54..1988.95 rows=166 width=189) (actual time=12694.159..12694.160 rows=8 loops=1)
Sort Key: assignedemployee.project_id DESC
Sort Method: quicksort Memory: 26kB
-> Hash Join (cost=427.77..1982.42 rows=166 width=189) (actual time=8625.176..12694.084 rows=8 loops=1)
Hash Cond: (assignedemployee.project_id = project.id)
-> Seq Scan on assignedemployee (cost=0.00..1549.64 rows=166 width=196) (actual time=8613.148..12665.380 rows=8 loops=1)
Filter: (status_of_assignment AND (upper(pgp_sym_decrypt(user_email, 'secret_key'::text)) = 'PAVEL@example.COM'::text))
Rows Removed by Filter: 33800
-> Hash (cost=397.90..397.90 rows=2390 width=443) (actual time=9.573..9.573 rows=2390 loops=1)
Buckets: 4096 Batches: 1 Memory Usage: 1150kB
-> Seq Scan on project (cost=0.00..397.90 rows=2390 width=443) (actual time=0.026..8.223 rows=2390 loops=1)
Planning time: 4.898 ms
Execution time: 12698.741 ms
だから私はインデックスを設定することにしました:
class Meta:
unique_together = (('user_email', 'project'), )
indexes = (models.Index(fields=['-status_of_assignment']),
models.Index(fields=['status_of_assignment']),
models.Index(fields=['user_email', '-status_of_assignment']),
models.Index(fields=['project']),
models.Index(fields=['-project']),
models.Index(fields=['user_email', '-status_of_assignment', '-project']),
models.Index(fields=['user_email', '-status_of_assignment', 'project']))
index_together = [
['user_email', 'status_of_assignment'],
]
私はdbeaverでそれらを見ることができますが、パフォーマンスとexplain()では何も変わりません。
インデックスを設定するにはどうすればよいですか、それとも問題は別の場所にあるのでしょうか?