【问题标题】:Raw queries and custom sql queries what is the fastest?原始查询和自定义 sql 查询哪个最快?
【发布时间】:2013-05-16 07:08:39
【问题描述】:

假设我的 应用程序 (webapp) 中的文件 models.py 如下所示:

from django.db import models
from django.db import connection

class Foo(models.Model):
    name = models.CharField(...)
    surname = models.CharField(...)

def dictfetchall(cursor):
    "Returns all rows from a cursor as a dict"
    desc = cursor.description
    return [
        dict(zip([col[0] for col in desc], row))
        for row in cursor.fetchall()
    ]

def get_foo():
    cursor = connection.cursor()
    cursor.execute('SELECT * FROM foo_table')
    rows = dictfetchall(cursor)
    return rows

要访问我的数据库内容,我基本上有两种选择:

选项 1:

from webapp.models import Foo
bar = Foo.objects.raw('SELECT * FROM foo_table')

选项 2:

from application.models import get_foo
bar = get_foo()

哪个选项执行速度最快? 有没有更好的方法来做我想做的事?

【问题讨论】:

  • 如果你不想利用好的抽象,为什么要使用 Django?除此之外,它是否需要尽可能快?以最易读、最易维护的方式去做,然后,如果你发现你迫切需要性能,优化瓶颈。
  • 另外,尝试将SELECT * 的结果转储到字典(在内存中)可能是不可取的。
  • 如果您只想选择每条记录,使用Foo.objects.all() 有什么问题?看看 QuerySet API - 大多数用例都可以用它解决。
  • Django 基本上执行“SELECT list all foo_table cols here FROM foo_table”,速度一样快。生成 cols 列表可能需要一些操作,但这没什么大不了的。尽管任何 DBA 都会告诉您,它确实可以保护您使用显式表 cols。保护来自显式,因此即使将来表结构因任何原因发生更改,您的代码也会更安全。
  • @sr2222 实际上我使用的是更复杂的请求,例如SELECT count(*) FROM Question inner join Ask on question_id=question_ask WHERE quiz_ask = %s

标签: django python sql django


【解决方案1】:

对于哪种方法更好,没有直接而明确的答案。

使用Manager.raw() 仍使您保持在ORM 层内,虽然它返回模型实例,但您仍然拥有一个很好的数据库抽象。但是,在进行原始查询时,django 不仅仅是 cursor.execute 将结果转换为 Model 实例(查看 RawQuerySetRawQuery 类中发生的情况)。

但是(引自docs):

有时甚至 Manager.raw() 还不够:您可能需要 执行不完全映射到模型的查询,或直接执行 UPDATE、INSERT 或 DELETE 查询。

所以,一般来说,选择什么取决于将要获得什么结果以及您将如何处理这些结果。

另见:

【讨论】:

  • 你说得对,django 在使用cursor.execute 时赚的比cursor.execute 还多,所以我有我的答案。我更喜欢使用游标与我的数据库交互,因为有些事情我不知道如何在 python 中完成,而使用 SQL 很容易。
【解决方案2】:

使用连接游标肯定比使用raw() 更快,因为它不会实例化附加对象...但是要真正告诉最快的解决方案是什么,您应该做一些基准测试!

如果没有必要,不要过度优化,因为只要你没有任何严重的性能问题,你就可以避免一些 Django 最有用的特性。如果你有一些,它们很可能不是你执行查询的结果。当然,如果您完全了解您的用例而 ORM 不了解,您将能够编写更好的查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    • 1970-01-01
    • 2018-05-15
    • 2015-11-21
    • 2012-03-16
    • 2014-04-15
    相关资源
    最近更新 更多