<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] >[success] # 常見錯誤N+1 問題 ~~~ 就是往往不注意循環中的orm 處理,導致出現N+1的問題,進而導致系統變慢, 然后拖垮整個系統。 ~~~ >[success] # 常見的幾種N+1 >[danger] ##### 沒有合理使用derfer ~~~ 1.derfer 是查詢除了什么字段以外的字段 2.下面是在單元測試寫的一個小案例,我們主要關心這段代碼 categories = Categroy.objects.defer('name') for i in categories: print(i.name) ~~~ ~~~ @override_settings(DEBUG=True) def set_filter(self): categories = Categroy.objects.exists() print(categories) categories = Categroy.objects.defer('name') for i in categories: print(i.name) print(categories) # categories = categories.filter(status=1) pp(connection.queries) ~~~ * 實際產生的sql ~~~ 1.第一次查詢,實在for i in categories 打印出來的,不是在創建的時候因為懶加載機制 ---'SELECT "blong_categroy"."id", "blong_categroy"."status", ' '"blong_categroy"."is_nav", "blong_categroy"."owner_id", ' '"blong_categroy"."created_time" FROM "blong_categroy"', 'time' 2.當我們i.name 由于derfer 是除了name 字段以外的字段查詢,我們 卻偏偏打印了這個字段就產生了下面N的情況 --'SELECT "blong_categroy"."id", "blong_categroy"."name" FROM ' '"blong_categroy" WHERE "blong_categroy"."id" = 1 乘循環次數的N,其中為什么是N次,因為我們給查詢每個id 的name,所以相當于執行了N次的where條件id=1 id=2 .....直到最后一個id ~~~ >[danger] ##### only ~~~ 1.only 是只查詢這個字段 2.下面是在單元測試寫的一個小案例,我們主要關心這段代碼 def set_filter(self): categories = Categroy.objects.only('name') for i in categories: print(i.created_time) ~~~ ~~~ @override_settings(DEBUG=True) def set_filter(self): categories = Categroy.objects.only('name') for i in categories: print(i.created_time) print(categories) # categories = categories.filter(status=1) pp(connection.queries) ~~~ * 實際產生的sql ~~~ 1.第一次查詢,實在for i in categories 打印出來的,不是在創建的時候因為懶加載機制 ---' 'SELECT "blong_categroy"."id", "blong_categroy"."name" FROM ' '"blong_categroy"' 2.當我們查詢i.created_time 由于only是只查詢什么字段, 導致由于id是唯一的所以,判斷條件要where 每一個id查詢結果 卻偏偏打印了這個字段就產生了下面N的情況 --'SSELECT "blong_categroy"."id", "blong_categroy"."created_time" FROM ' '"blong_categroy" WHERE "blong_categroy"."id" = 1', 乘循環次數的N,其中為什么是N次,因為我們給查詢每個id created_time,所以相當于執行了N次的where條件id=1 id=2 .....直到最后一個id ~~~ >[danger] ##### 關聯對象 ~~~ 1.當我們兩個表做了關聯的時候也就是ForeignKey的時候,我們可能最容易忽略 這個n+1的問題,兩個表的關聯查詢 在sql語句上我們通常使用jion on 如果不使 用,我們看看執行情況,這是表的創建展示 class Categroy(models.Model): STATUS_ITMES = ( (1, "正常"), (2, "刪除"), ) name = models.CharField(max_length=50, verbose_name="名稱") status = models.PositiveIntegerField(default=1, choices=STATUS_ITMES, verbose_name="狀態") is_nav = models.BooleanField(default=False, verbose_name="是否為導航") owner = models.ForeignKey(User, verbose_name="作者") created_time = models.DateTimeField(auto_now_add=True, verbose_name="創建時間") class Meta: verbose_name = verbose_name_plural = '分類' ~~~ * 問題我們想去查關聯表,我們來看看 常見的N+1 錯誤 ~~~ @override_settings(DEBUG=True) def set_filter(self): categories = Categroy.objects.all() for i in categories: print(i.owner) # categories = categories.filter(status=1) pp(connection.queries) ~~~ ~~~ 1.上面的代碼有一個很嚴重的N+1問題 2.其實每一打印的owner 對象實際是又重新生成了sql 語句,如下展示 --- SELECT "blong_categroy"."id", "blong_categroy"."name", ' '"blong_categroy"."status", "blong_categroy"."is_nav", ' '"blong_categroy"."owner_id", "blong_categroy"."created_time" FROM ' '"blong_categroy"', 'time' 3.打印查詢了N邊的,其中N 是where 條件中的id ----'SELECT "auth_user"."id", "auth_user"."password", ' '"auth_user"."last_login", "auth_user"."is_superuser", ' '"auth_user"."username", "auth_user"."first_name", ' '"auth_user"."last_name", "auth_user"."email", ' '"auth_user"."is_staff", "auth_user"."is_active", ' '"auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = ' '1', ~~~ * 怎么解決這樣問題--select_related() 來解決這個問題 ~~~ @override_settings(DEBUG=True) def set_filter(self): categories = Categroy.objects.select_related().filter(status=1) for i in categories: print(i.owner) # categories = categories.filter(status=1) pp(connection.queries) ~~~ * 執行的sql 語句用jion on 吧ower 對象查詢,這樣我們就可以直接操對象而不是他的本身 ~~~ 'SELECT "blong_categroy"."id", "blong_categroy"."name", ' '"blong_categroy"."status", "blong_categroy"."is_nav", ' '"blong_categroy"."owner_id", "blong_categroy"."created_time", ' '"auth_user"."id", "auth_user"."password", "auth_user"."last_login", ' '"auth_user"."is_superuser", "auth_user"."username", ' '"auth_user"."first_name", "auth_user"."last_name", ' '"auth_user"."email", "auth_user"."is_staff", ' '"auth_user"."is_active", "auth_user"."date_joined" FROM ' '"blong_categroy" INNER JOIN "auth_user" ON ' '("blong_categroy"."owner_id" = "auth_user"."id") WHERE ' '"blong_categroy"."status" = 1', ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看