運行兩個類似的查詢,如不Rails的自動的優化查詢
@articles = @magazine.articles.limit(2).offset(0)
@articles = @articles.limit(2).offset(2)
,我期待看到我的控制檯兩個SQL語句由服務器執行之後。但是,第一個查詢丟失,只有第二個查詢正在運行。同樣,執行以下兩個查詢後:
@articles = @magazine.articles.limit(2).offset(0)
@articles = @articles.limit(2).offset(@articles.size - 2)
第一個查詢也被完全忽略。這兩個查詢生成SQL:
SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM "articles"
WHERE "articles"."magazine_id" = $1 LIMIT 2 OFFSET 0)
subquery_for_count [["magazine_id", 1]]
SELECT "articles".* FROM "articles"
WHERE "articles"."magazine_id" = $1
LIMIT 2 OFFSET 2 [["magazine_id", 1]]
有趣的是,如果我改變@articles.size
到@articles.length
兩種查詢按預期運行。我會認爲,因爲length
需要在內存中收集,第一條語句被迫運行。任何人都可以描述這裏發生了什麼,如果它是一個太廣泛的話題,請將我指向一個好的資源。
至於它爲什麼這樣工作:聲明的結束無法確定。鏈中的每個方法都會返回先前構建的查詢的變體版本。但是沒有辦法確定一個方法是否是鏈中的最後一個,並且它是否應該獲取數據。呃......對於惰性迭代器,沒有像'force'這樣的方法嗎? –
我對控制檯的信任確實讓我更加滿意。<。對延遲加載做了一些更多的閱讀,現在我更好地理解這個問題。非常感謝! – Steve