用範例程式實際探索 N + 1 query 有多可怕

Sky
2 min readMay 23, 2016

參考 Ruby Performance Optimization 的第三章 Make Rails Faster 裡面提到的範例,實際查看 N + 1 query 問題會有多可怕的問題

範例的情境

minions 這個 table 有 10 個字串欄位,每個 minion record 這 10 個字串欄位的字串長度都是 100

Thing has_many Minions , things 總共有 10000 筆資料,每筆 thing record 有關聯 10 個 minions , minions 的 thing_id 有加 index

一筆一筆取( N + 1 )

查看 10000 筆 thing record ,如果用一筆一筆的方式去把關聯的 minions 取出來,總共要花費的時間和記憶體用量

總共取 10000 * 10 = 100000 筆 minion record 出來,但是用 10000 個 query 做,結果如下:

一次撈

可以發現差距十分驚人! 360 秒 vs 10 秒,這只不過是從資料庫透過 ActiveRecord 拉出約 1xx MB 的資料量而已(會看到 console 寫 4xx MB ,是因為建立 ActiveRecord 物件有多餘的記憶體成本),就有如此差距,根據實務上面對的問題和挑戰不同,這差距可能更大或更小

小心 N + 1 query 問題,特別是資料量不小的時候,如果搜尋用的欄位還沒加索引,那更會是一場悲劇…

--

--