为什么django order_by在很多人的查询中都这么慢?

时间:2013-10-13 20:52:59

标签: python mysql django django-models django-orm

我有一个ManyToMany字段。像这样:

class Tag(models.Model):
    books = models.ManyToManyField ('book.Book', related_name='vtags', through=TagBook)

class Book (models.Model): 
    nump = models.IntegerField (default=0, db_index=True)           

我有大约450,000本书,而对于某些标签,它涉及约6万本书。当我做了如下查询:

tag.books.order_by('nump')[1:11]

变得非常缓慢,比如3-4分钟。 但是,如果我删除order_by,它会正常运行查询。

order_by版本的原始sql如下所示:

'SELECT `book_book`.`id`, ... `book_book`.`price`, `book_book`.`nump`, 
FROM `book_book` INNER JOIN `book_tagbook` ON (`book_book`.`id` =    
`book_tagbook`.`book_id`) WHERE `book_tagbook`.`tag_id` = 1  ORDER BY 
`book_book`.`nump` ASC LIMIT 11 OFFSET 1'

你对此有什么想法吗?我该怎么办呢?感谢。

--- --- EDIT

在mysql中检查以前的原始查询为@bouke建议:

SELECT `book_book`.`id`, `book_book`.`title`, ... `book_book`.`nump`, 
`book_book`.`raw_data` FROM `book_book` INNER JOIN `book_tagbook` ON 
(`book_book`.`id` = `book_tagbook`.`book_id`) WHERE `book_tagbook`.`tag_id` = 1  
ORDER BY `book_book`.`nump` ASC LIMIT 11 OFFSET 1;
11 rows in set (4 min 2.79 sec)

然后使用explain来找出原因:

+----+-------------+--------------+--------+---------------------------------------------+-----------------------+---------+-----------------------------+--------+---------------------------------+
| id | select_type | table        | type   | possible_keys                               | key                   | key_len | ref                         | rows   | Extra                           |
+----+-------------+--------------+--------+---------------------------------------------+-----------------------+---------+-----------------------------+--------+---------------------------------+
|  1 | SIMPLE      | book_tagbook | ref    | book_tagbook_3747b463,book_tagbook_752eb95b | book_tagbook_3747b463 | 4       | const                       | 116394 | Using temporary; Using filesort |
|  1 | SIMPLE      | book_book    | eq_ref | PRIMARY                                     | PRIMARY               | 4       | legend.book_tagbook.book_id |      1 |                                 |
+----+-------------+--------------+--------+---------------------------------------------+-----------------------+---------+-----------------------------+--------+---------------------------------+
2 rows in set (0.10 sec)

对于table book_book:

mysql> explain book_book;
+----------------+----------------+------+-----+-----------+----------------+
| Field          | Type           | Null | Key | Default   | Extra          |
+----------------+----------------+------+-----+-----------+----------------+
| id             | int(11)        | NO   | PRI | NULL      | auto_increment |
| title          | varchar(200)   | YES  |     | NULL      |                |
| href           | varchar(200)   | NO   | UNI | NULL      |                |
 ..... skip some part.............
| nump           | int(11)        | NO   | MUL | 0         |                |
| raw_data       | varchar(10000) | YES  |     | NULL      |                |
+----------------+----------------+------+-----+-----------+----------------+
24 rows in set (0.00 sec)

0 个答案:

没有答案