Django另一个优化save()

标签 django django-models query-optimization

在我的应用程序中优化查询的过程中,我注意到一些奇怪的事情。在给定的代码部分中,我将获取对象,更新一些值,然后保存。理论上这应该执行 2 个查询。但实际上它执行了 3 个查询。当我获取对象时,1 个选择查询,当我保存对象时,2 个选择查询(另一个选择,然后更新!)。虽然删除一个查询可能看起来很愚蠢。在这个特定的方法中,我正在更新许多对象,因此我保存的每个查询对数据库的命中减少了 1 个,并且应该加快该方法的速度。

通过检查查询,两个选择查询是不同的,第一个查询得到很多东西,而执行的选择很简单。

这里是示例代码:

            myobject = room.myobjects.get(id=myobject_id) # one query executed here
            myobject.color = color
            myobject.shape = shape
            myobject.place = place
            myobject.save() # two queries executed here

查询:

   1) "SELECT `rooms_object`.`id`, `rooms_object`.`room_id`, ......FROM `rooms_object` WHERE (`rooms_object`.`id` = %s AND `rooms_object`.`room_id` = %s )"

   2) "SELECT (1) AS `a` FROM `rooms_object` WHERE `rooms_object`.`id` = %s LIMIT 1"

   3) "UPDATE ......this ones obvious"

我希望 save 方法能够识别它已经在内存中拥有该对象,并且不需要再次获取它......如果可能的话......

最佳答案

第二个查询实际上并没有再次拉取对象。在执行 UPDATE 查询之前,它会对 id 进行极快的“存在”检查。该查询返回的所有内容都是单个 1,并且该字段已建立索引,因此它应该非常高效。

他们选择以这种方式设计 ORM 的原因是,他们首先查看您的对象以查看它当前是否有 ID。如果存在,他们会执行 SELECT 以确保它确实仍然存在于数据库中。如果是,他们就会执行更新。如果不知何故该记录不存在,它们会执行INSERT。您可以通过创建对象来测试这一点,然后在 django 不知情的情况下从数据库中手动删除该行。然后调用save()

这就是确保 django 保持一致性的工作原理。

如果它是一个新对象,您只会得到一个 INSERT 查询,因为它知道该对象现在没有 id

关于Django另一个优化save(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12117183/

相关文章:

python - 构造新的 django 模型对象,而不将所有相关模型加载到内存中

python - 我使用 django 连接池的多线程代码没有任何改进

Django 模型表单 "unique=True"

Django - 尝试访问时出错

php - MySQL优化: Perform Maths operation inside or outside of a query?

Django-filter:按模型属性过滤

django - 无法连接到redis ://localhost:6379/0: Error 111 connecting to localhost:6379. 连接被拒绝

sql - 查询以获取日期范围内的计数、小计和总计

sql - 如何根据行类型获取每种类型的最新行并执行计算?

sql - DB2 中 WHERE 子句求值顺序的优化