2017-10-13 20 views
3

我想在Django中將查詢傳遞給PostgreSQL數據庫。當我使用大量的ID過濾我的查詢時,查詢非常緩慢並且上升到70s。Django查詢過濾器在Postgres數據庫中使用大量ID的ids

尋找一個答案,我看到this post這給出了一個解決我的問題後,只需通過VALUES (id1), (id2), ...改變ARRAY [ids]在IN聲明。

我測試的解決方案與pgAdmin的原始查詢,查詢變爲從70年代到300毫秒......

我如何可以做同樣的命令(即不使用一組ID但值的查詢)在Django?

+0

可以請你發佈你的實際Django過濾器查詢嗎? – efkin

回答

0

訣竅是變換陣列到設置不知何故

代替(這種形式只有很短的陣列良):


               
    
      SELECT * FROM tbl t WHERE t.tbl_id = ANY($1); -- WHERE t.tbl_id IN($1); -- equivalent 
    

$1是所述數組參數。

你仍然可以通過一個數組像你一樣,但不加入和加入。像:

SELECT * 
FROM tbl t 
JOIN unnest($1) arr(id) ON arr.id = t.tbl_id; 

或者你可以保持您的查詢,也不過替換子查詢的陣列unnesting它:

SELECT * FROM tbl t 
WHERE t.tbl_id = ANY (SELECT unnest($1)); 

或者:

SELECT * FROM tbl t 
WHERE t.tbl_id IN (SELECT unnest($1)); 

的性能傳球效果相同a 設置VALUES表達。但傳遞數組通常要簡單得多。

詳細說明:

0

這是你問的第一件事就是一個例子嗎?

relation_list = list(ModelA.objects.filter(id__gt=100)) 
obj_query = ModelB.objects.filter(a_relation__in=relation_list) 

這將是一個「IN」命令,因爲你第一次用它強制轉換爲list,然後在你的第二個查詢使用它評估relation_list

如果您完全相同,Django只會進行一個查詢,併爲您執行SQL優化。所以它應該更有效率。

如果您對引擎蓋下正在發生的事情感到好奇,您隨時都可以看到您將執行的SQL命令obj_query.query

希望能回答這個問題,如果不是的話,很抱歉。