Mysql 如何在Django中减少查询时的数据库命中数
我有三张桌子Mysql 如何在Django中减少查询时的数据库命中数,mysql,django,django-models,Mysql,Django,Django Models,我有三张桌子 使用者 装置 日志 我想根据设备和日志过滤日志。我正在使用下面的查询,它迭代用户和设备以获取日志。我觉得这将成为一个性能打击。如何减少数据库命中数 for user_obj in User.objects.all(): device_qs = Device.objects.filter(user=user_obj) if device_qs.exists(): for device_obj in device_qs: log_
for user_obj in User.objects.all():
device_qs = Device.objects.filter(user=user_obj)
if device_qs.exists():
for device_obj in device_qs:
log_count = Log.objects.filter(user=user_obj, device=device_obj, created_at__range(from_date, to_date)).count()
我要做的是创建一个“代理模型”,它引用MySQL实例中的
视图
视图如下所示:
SELECT
t1.*,
t2.*,
t3.*
FROM users t1
RIGHT JOIN device t2 (ON t1.id=t2.user_id)
RIGHT JOIN log t3 (ON t3.device_id=t2.id);
from django.db import connection
sql = "SELECT * FROM your_view WHERE some_date_column > 'foo' AND some_date_column < 'bar' "
with connection.cursor() as cur:
cur.execute(sql)
data = cur.fetchall()
print(data)
现在要创建代理模型,请执行以下操作:
class SomeModel(models.Model):
# all fields from the 3 tables here
class Meta:
db_table = 'yourViewNameHere'
managed = False # this keeps django from creating the table
然后像往常一样python manage.py makemigrations
+python manage.py migrate
现在,要访问所需的数据,您可以执行以下操作:
SELECT
t1.*,
t2.*,
t3.*
FROM users t1
RIGHT JOIN device t2 (ON t1.id=t2.user_id)
RIGHT JOIN log t3 (ON t3.device_id=t2.id);
from django.db import connection
sql = "SELECT * FROM your_view WHERE some_date_column > 'foo' AND some_date_column < 'bar' "
with connection.cursor() as cur:
cur.execute(sql)
data = cur.fetchall()
print(data)
从django.db导入连接
sql=“从您的视图中选择*,其中一些日期列>“foo”和一些日期列<“bar”
将connection.cursor()作为cur:
当前执行(sql)
data=cur.fetchall()
打印(数据)
注意如果要将参数传递给原始sql查询,则应始终这样传递参数,以避免sql注入:
sql = "SELECT * FROM your_view WHERE some_date_column > %s AND some_date_column < %s"
params = ('foo', 'bar')
with connection.cursor() as cur:
cur.execute(sql, params)
data = cur.fetchall()
sql=“从您的视图中选择*,其中一些日期列>%s和一些日期列<%s”
参数=('foo','bar')
将connection.cursor()作为cur:
当前执行(sql,参数)
data=cur.fetchall()
如果您只需要每个用户和设备的日志计数(这是您从发布的代码中获得的),只需一次查询即可获得:
from django.db.models import Count
logs = (Log.objects
.filter(created_at__range = (from_date, to_date))
.values('user', 'device')
.annotate(log_count=Count('device'))
)
您可以修改查询以包括所需的用户和设备型号的任何属性:
.values('user__last_name', 'device__name') # etc.
您还可以通过在末尾添加order\u by()
对数据集进行排序,以便能够按所需顺序对其进行迭代:
.order_by('user__last_name', '-log_count')
你在用什么数据库?@Jane在用MySQL数据库后端你有模型的代码吗?显示模型之间关系的部分模型就足够了。感谢您的详细回答,尤其是在此标准中使用代理模型。但是我的问题是,有没有一种方法可以使用Django ORM的查询方式来避免编写直接的MySQl查询此查询跳过没有日志的设备。但我希望在没有日志时使用0更新日志。提前感谢。这样您就不用再查询用户
(或设备
)型号了。您必须使用三个模型的代码更新问题,以便我们可以考虑查询。您只想要没有日志的设备还是想要没有日志的用户?我想要与用户关联的所有设备日志(计数),而不考虑日志计数(有日志还是没有日志),让用户处于值中就可以了。