2014-04-28 63 views
1

我有以下的數據庫結構:優化Django管理SQL

class Book(models.Model): 
    id = models.AutoField(primary_key=True, db_column='id') 
    name = models.CharField(max_length=255, db_column='name') 
    author = models.ForeignKey('Author', to_field='id', db_column='author_id') 


class Author(models.Model): 
    id = models.AutoField(primary_key=True, db_column='id') 
    fio = models.CharField(max_length=255, db_column='fio') 

    def __unicode__(self): 
     return self.name 

而這個管理類圖書:

class BookAdmin(admin.ModelAdmin): 
    list_display = ('id', 'name',) 
    fields = ('id', 'name', 'author',) 
    readonly_fields = ('id',) 
    raw_id_fields = ('author',) 

一切正常時,它的500-1000書中記載,但1- 200萬本書頁面凍結了幾分鐘之後才顯示出某種東西。 Profiler告訴我,django與作者一起加入書籍,然後剪下最後的100條記錄。

SELECT ••• FROM `books` INNER JOIN `authors` ON (`books`.`author_id` = `authors`.`id`) ORDER BY `books`.`id` DESC LIMIT 100 

從數據庫中選擇書籍後,如何優化django以加入作者?或者使用類似的東西

select * from (SELECT * FROM books ORDER BY books.id DESC LIMIT 100) t, authors a where t.author_id = a.id 

回答

1

你遇到一個已知的問題:Slow INNER JOIN in MySQL can be fixed in Django ORM, but should it?

有一個名爲django-mysql-fix項目,該項目開始介紹了一個自定義的MySQL數據庫後端的專門固定INNER JOIN問題PYCON 2014衝刺:

該項目包含針對Django ORM的MySQL的優化(黑客)。

有兩個非常簡單的方法來cacth INNER JOIN錯誤:

  • 一旦你在你的Django管理模型list_display指定外國表字段;

  • 一旦您嘗試按字段從外部表中排序(排序)。

據我瞭解,在引擎蓋下它取代所有INNER JOIN s的STRAIGHT_JOIN S,引自mysql docs

STRAIGHT_JOIN類似於JOIN,除了左表總是 在右表之前閱讀。這可以用於連接優化程序以錯誤順序放置表的那些(少數)案例 。

另見:

+0

這會影響PostgreSQL的呢? –

+0

@BurhanKhalid我很肯定這是mysql特有的。謝謝。 – alecxe