2017-06-02 24 views
1

我正在學習Django及其ORM數據訪問方法,並且有一些我很好奇。在一個特定的終點,我做了一些數據庫調用(以Postgres的) - 下面是一個示例:Django QuerySet與原始SQL性能注意事項

projects = Project.objects\ 
      .filter(Q(first_appointment_scheduled=True) | (Q(active=True) & Q(phase=ProjectPhase.meet.value)))\ 
      .select_related('customer__first_name', 'customer__last_name', 
          'lead_designer__user__first_name', 'lead_designer__user__last_name')\ 
      .values('id')\ 
      .annotate(project=F('name'), 
         buyer=Concat(F('customer__first_name'), Value(' '), F('customer__last_name')), 
         designer=Concat(F('lead_designer__user__first_name'), Value(' '), F('lead_designer__user__last_name')), 
         created=F('created_at'), 
         meeting=F('first_appointment_date'))\ 
      .order_by('id')[:QUERY_SIZE] 

正如你可以看到,這是一個不小的查詢 - 我拉在很多具體的相關數據和做一些字符串操作。我比較關心性能,所以我盡我所能,通過使用select_related()values()來獲得我需要的東西,從而提高效率。

我的問題是,在概念上和廣義上講,使用參數化SQL而不是使用ORM編寫我的查詢會變得更快 - 因爲ORM必須首先「翻譯」上述「混亂「)?在什麼樣的查詢複雜性水平下,我應該切換到原始SQL?

任何洞察將有所幫助。謝謝!

回答

3

這個問題我已經是,概念從廣義上講,在什麼點 它變得更快,只是使用參數化SQL ,而不是使用ORM(因爲ORM必須首先「翻譯」寫我的查詢上面的「爛攤子」上的 )?

如果您詢問性能,從不。

將ORM查詢轉換爲SQL的時間與實際執行該查詢所用的時間相比非常小。 Braincells是不可替代的,服務器很便宜。

如果您真的關心性能,首先要看的是您的索引。嘗試打印ORM生成的每個查詢,並通過在EXPLAIN ANALYZE前加前綴在psql控制檯中運行它們。

在什麼近似水平的查詢複雜度下,我應該切換到 原始SQL?

如果您問的是編碼的簡易性,那要看情況。

如果查詢非常難以使用ORM編寫,並且它是不可讀的,那麼使用原始查詢是完全正確的。

1

同意@ e4c5的說法。

將ORM查詢轉換爲原始SQL查詢的其他轉換層將影響性能。

但是,這種效果將取決於您的查詢有多複雜?

當您使用ORM時,您可以通過增加應用程序中的處理來控制數據庫的負載。另外,這提供了將結果緩存在應用程序本身中的機會。

最後,這完全取決於你的模式,你的查詢的複雜程度以及你是如何縮放您的DB(指數,副本等)

更多閱讀here

+0

好文章。我想我可能會打印出該圖。 – Snowie

+0

很高興你喜歡它,如果你喜歡它,請upvote我的答案。謝謝 – tom

+0

'用於將ORM查詢轉換爲原始SQL查詢的附加翻譯層將影響性能'如果您執行基準測試,則會發現完全相反。效果可以忽略不計。 – e4c5