我在为我的查询建立正确的索引时遇到了问题。
我有一个这样的模型:
from django.db import models
class Record(models.Model):
user = models.ForeignKey(User, db_index=True, related_name='records')
action = models.ForeignKey(Action, db_index=True)
time = models.DateTimeField(db_index=True, default=timezone.now)
class Meta:
index_together = (
('user', 'time'),
('action', 'user', 'time'),
)
如您所见,此模型有两个自定义索引。
如果我想获取与特定用户相关的所有记录,按 time
过滤,我使用此查询:user.records.filter(time__gt=some_moment)
。它工作正常并使用第一个自定义索引(根据 Django Debug Toolbar )。
现在,在我的情况下,结果必须按 action
排序。我使用此查询:user.records.filter(time__gt=some_moment).order_by('action')
。
但是,尽管存在适当的索引,但并未使用它。
我做错了什么?如何为这个查询建立正确的索引?
Django 版本 = 1.8.4,应用所有迁移,数据库后端 = mysql。
UPD:有我的查询:
SELECT *** FROM `appname_record`
WHERE (`appname_record`.`user_id` = 1896158 AND
`appname_record`.`time` > '2015-10-19 06:39:30.992790')
ORDER BY `appname_record`.`action_id` ASC
有完整的django工具栏解释:
ID: 1
SELECT_TYPE: SIMPLE
TABLE: appname_record
TYPE: ALL
POSSIBLE_KEYS:
appname_record_user_id_3214bab8a46891cc_idx, appname_record_07cc694b
KEY: None
KEY_LEN: None
REF: None
ROWS: 240
EXTRA: Using where; Using filesort
有 mysql show create table appname_record;
关于键的部分:
PRIMARY KEY (`id`),
KEY `appname_record_action_id_3e42ba1d5288899c_idx` (`action_id`, `user_id`,`time`),
KEY `appname_record_user_id_3214bab8a46891cc_idx` (`user_id`,`time`),
KEY `appname_record_07cc694b` (`time`),
所以看起来正确的索引甚至不在可能的键中。
最佳答案
如果一个查询根本不使用任何索引,那通常是因为表中没有足够的数据来使索引真正有用。然而,对于 500 条记录,索引很有可能应该发挥作用。
在您使用的查询中,appname_record_user_id_3214bab8a46891cc_idx
确实是可能的候选者,但仍未使用。为什么?因为您的查询显然会导致数据库查看大约一半的表,因为这样的索引无法加快速度。
您删除一个索引似乎是在正确的轨道上。两个许多相似的索引也不是很有用。我会试试这个索引:
class Meta:
index_together = (
('user', 'time','action'),
)
这里的区别在于字段的顺序。这是 important :
MySQL can use multiple-column indexes for queries that test all the columns in the index, or queries that test just the first column, the first two columns, the first three columns, and so on. If you specify the columns in the right order in the index definition, a single composite index can speed up several kinds of queries on the same table.
关于python - 如何使用 Django 的 index_together 与 filter 和 order_by 一起查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33186938/