Django之ORM查詢優化

res = models.Book.objects.all()
    # 若是此時直接運行,不調用這個結果,終端將什麼也不會打印出來
    # 緣由:惰性查詢,減小沒必要要的數據庫操做,下降數據庫的壓力

only 和 defer

only 的優化機制:sql

res = models.Book.objects.only('title')     # 括號內查詢的字段能夠有多個
print(res)        # 查詢一次,打印一條sql查詢語句
for i in res:
    print(i.title)  # 查詢一次,打印一條sql查詢語句
    print(i.price)  # 有幾個對象,就查詢幾回,打印幾條sql查詢語句

defe 的優化機制:數據庫

res = models.Book.objects.defer('title')    # 括號內查詢的字段能夠有多個
print(res)              # 查詢一次,打印一條sql查詢語句
for i in res:
    print(i.title)      # # 有幾個對象,就查詢幾回,打印幾條sql查詢語句
    print(i.price)        # 查詢一次,打印一條sql查詢語句

only 與 defer 的區別:app

共同點:二者括號內均可以放數據庫字段,查詢結果都是一個列表套一個個的數據對象。fetch

不一樣點:優化

  • only:數據對象裏面封裝了括號內查詢的字段,直接點這個括號內字段屬性不須要再次查詢數據庫設計

    ​ 若是查詢括號內沒有的字段,每查詢一次,就須要去數據庫中從新查詢,效率低code

  • defer:數據庫中封裝了至關於除括號內查詢的字段,直接點這個括號內字段屬性須要再次查詢數據庫,若是查詢括號內沒有的字段,就不須要再次查詢數據庫,效率高orm

select_related 和 prefetch_related

select_related :對象

res = models.Book.objects.select_related('publish') # 支持放多個外鍵字段
print(res)      # 查詢外鍵字段,連表查詢
for i in res:
    print(i.publish.name)   # 連表查詢一次,一條sql語句
    print(i.title)          # 連表查詢一次,一條sql語句

prefetch_related:

res = models.Book.objects.prefetch_related('publish')   # 支持放多個外鍵字段
print(res)  # 查詢外鍵字段,子查詢
for i in res:
    print(i.publish.name)  # 子查詢查詢一次,一條sql語句
    print(i.title)  # 子查詢查詢一次,一條sql語句

select_related 和 prefetch_related 的區別:

共同點:括號內只能放外鍵字段,而且外鍵字段關係只能是一對多、一對一,不能是多很少

不一樣點:

  • select_related:內部是連表(left/right join)查詢,查詢的時候不須要再次查詢數據庫
  • prefetc_related:內部是子查詢,查詢多張表,將查詢結果封裝到對象中,若是括號內外鍵字段比較多,則查詢次數較多。

結合實際狀況,哪一種查詢更加好?

select_related 查詢須要連表,數據量大可能耗時比較久

prefetc_related 查詢多張表,數據量大可能查詢次數多一點,可是時間較快

ORM字段參數 choices

字段參數choices能夠按照提早設計好的對應關係,存取對應真正的數據

models.py:
class User(models.Model):
    user = models.CharField(max_length=64)
    pwd = models.IntegerField()
    gender_choices = (
        (1,'男'),
        (2,'女')
    )
    gender = models.IntegerField(choices=gender_choices)
    

手動插入數據:
id  user    pwd gender
1   qinyj   123 1
2   jack    123 2
from app01 import models
user_obj = models.User.objects.get(pk=1)
print(user_obj.get_gender_display())

只要是choices字段類型,在獲取值的時候須要這樣寫:get_字段名_display()

相關文章
相關標籤/搜索