PostgreSQL 如何处理 Django 中的 get() 以获得精确的文件路径匹配及其性能?

问题描述 投票:0回答:1

我将 Django 与 PostgreSQL 数据库结合使用,并且我有一个模型将文件路径(特别是 S3 文件路径)存储在 CharField 中,如下所示:

class File(models.Model):
    file_path = models.CharField(max_length=255)

我经常使用 Django 的 get() 方法检索单个文件记录,并且与 S3 文件路径完全匹配:

file = File.objects.get(file_path='/bucket/path/to/file.txt')

这将转换为以下 SQL 查询:

SELECT * FROM my_table WHERE file_path = '/bucket/path/to/file.txt' LIMIT 1;

我想了解 PostgreSQL 处理这个查询时幕后发生了什么。具体来说:

1.  How does PostgreSQL handle the comparison of strings when using the = operator on a CharField with an S3 file path?
2.  Does PostgreSQL behave differently if there’s an index on the file_path column, and how does it decide between using an index or performing a sequential scan?
3.  Is it beneficial to create an index on the file_path field for better performance,
django postgresql
1个回答
0
投票

如果您知道 Django 中的查询集如何工作,您会发现它只是将 ORM 表示法转换为纯文本

SQL
例如:

File.objects.get(file_path='/bucket/path/to/file.txt')

它将转变为如下所示:

SELECT * FROM "appname_file" WHERE "file_path" = '/bucket/path/to/file.txt' LIMIT 1;

在这种情况下,如果

file_path
不是索引,那么 SQL 引擎执行
Execution Plan
它将执行一个名为:
FULL SCAN
的操作,这意味着它肯定会扫描表中不是索引的所有行。就性能而言确实非常高效。

如果您决定创建索引

file_path
,它将做一些非常不同的事情,因为它存储了名为
Data pages or Leaf nodes
的内容,其中包含记录子集分配位置的映射,因此它将查询
data_pages
并从那里开始它将获取该行的唯一标识符,并且不会执行
FULL SCAN

注意事项:

  • 对于您的用例,如果您没有很多索引,我认为创建一个索引是一个很好的案例。
  • 您可以使用sql中的
    EXPLAIN
    关键字评估生成计划的性能,并可以分析结果。
  • 如果你想更深入地了解它,你可以使用
    EXPLAIN ANALYZE
    ,它不仅会给你执行计划,还会给你执行时间。
  • 您可以使用django获取执行计划,如下所示:
from django.db import connection
sql = 'EXPLAIN SELECT * FROM appname_file WHERE file_path=%s LIMIT 1;'
params = ['/bucket/path/to/file.txt']
with connection.cursor() as cursor:
    cursor.execute(sql, params):
    plan = cursor.fetchall()

print(plan)

我鼓励您进行自己的性能评估,看看索引是否适合您的用例,我想如果

appname_file
对于每一行都是唯一的,它会特别有效。

© www.soinside.com 2019 - 2024. All rights reserved.