2

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 冊の本を持っており、いくつかのタグについては、約 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