2

我有一个多对多字段。像这样:

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 本书,对于某些标签,它与大约 60,000 本书相关。当我进行如下查询时:

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'

你对此有什么想法吗?我该如何解决?谢谢。

- -编辑 - -

按照@bouke 的建议,检查了mysql 中的先前原始查询:

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)

然后使用解释找出原因:

+----+-------------+--------------+--------+---------------------------------------------+-----------------------+---------+-----------------------------+--------+---------------------------------+
| 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)

对于表 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)
4

0 回答 0