gpt4 book ai didi

mysql - 使用 Django queryset 查询日期对象有性能问题

转载 作者:行者123 更新时间:2023-11-29 01:54:34 25 4
gpt4 key购买 nike

我正在使用 django 1.8.4 编写一个网络应用程序。后端使用 MySQL 5.6 (MyISAM)。最近表记录数达到100万条,查询所有不同的记录日期需要1-1.5秒。但是使用MySQL客户端,不到0.001秒。

Django 代码

class Model1(models.Model):
date = models.DateField(db_index=True)

# benchmark code
db_dates = Model1.objects.dates("date", kind="day")

MySQL 查询:

SELECT date FROM `table1` group by date ORDER BY `date` ASC

MySQL 客户端说:总共 620,查询耗时 0.0025 秒。


更新1

关于@e4c5 提示,我放弃了 django 查询。实际上查询中有一个类型转换。这是慢的根本原因。

{u'time': u'1.989', 
u'sql': u"SELECT DISTINCT CAST(DATE_FORMAT(`model1_table`.`date`, '%Y-%m-%d 00:00:00') AS DATETIME) AS `datefield` FROM `model1_table` WHERE `model1_table`.`date` IS NOT NULL ORDER BY `datefield` ASC"}

即使我在 MySQL 客户端中手动运行查询,它也会变慢。我注意到第二个查询进行了类型转换。

是否需要类型转换(datedatetime)?我该如何解决这个问题?

无论如何,我已经发射了一个issue here用于跟踪。

最佳答案

根本原因

Django 在内部生成这样一个查询:

SELECT DISTINCT 
CAST(
DATE_FORMAT(`model1_table`.`date`, '%Y-%m-%d 00:00:00') AS DATETIME
) AS `datefield`
FROM `model1_table` WHERE `model1_table`.`date` IS NOT NULL
ORDER BY `datefield` ASC"

显然,所有 DATE 字段首先转换为 DATETIME,然后使用其日期部分。性能影响与记录数量成比例。

解决方案

  1. 正如@e4c5 提到的,我们可以使用

results = set(obj.date for obj in Model1.objects.distinct('date'))

但这只适用于 PostgreSQL。它不适用于 MySQL。我们将收到错误消息:“此数据库后端不支持 DISTINCT ON 字段”。

  1. @BurhanKhalid 的回答会将所有日期对象检索到客户端,这也很慢。我很快发现我们可以添加一个 distinct 来过滤来自服务器端的结果。

这是我修改后的版本。

results = set(Model1.objects.order_by('date').values_list('date', flat=True).distinct())

现在从 150 万条记录中查询不同的日期字段只需要 0.004 秒。酷!

关于mysql - 使用 Django queryset 查询日期对象有性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32795047/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com