python - 如何使用 Django 的 index_together 与 filter 和 order_by 一起查询?

标签 python mysql django indexing

我在为我的查询建立正确的索引时遇到了问题。
我有一个这样的模型:

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/

相关文章:

MySQL UTF/Unicode 迁移技巧

mysql - SQL MIN 无法正常工作

java - 如何在 Spring 生态系统中使用 JPA hibernate 连接到不同的 mysql 数据库模式?

python - 如何循环遍历 Pandas 数据框

python - 我怎样才能既注册蓝图又将该应用程序添加到 flask 管理员

python - 在 Python 中使用整数除法

django 如何为 postgresql 数据库中现有的多对多表定义模型

python - 在内存中加载大型字典的巨大内存使用量

python - Factory_boy 不创建不同的用户对象 Django

python - 如何在 Django 中将列表从一个 View 传递到另一个 View ?