2015-09-12 48 views
4

我有一個性能相關的Django查詢問題。Django查詢性能

假設我有一張擁有10,000條記錄的員工表。現在,如果我要選擇年齡大於或等於20歲的5名隨機僱員,假設有5,500名員工年齡在20歲或以上。 Django的查詢是:

Employee.objects.filter(age__gte=20).order_by('?')[:5] 

與此查詢在mysql中的原始副本將是:

SELECT * FROM `database`.`employee` 
WHERE `employee`.`age` >= 20 
ORDER BY RAND() 
LIMIT 5; 

從Django中的長相查詢數據庫首先返回5500條記錄,那麼Python各種各樣這些記錄隨機或我們選擇的任何順序,並返回一大塊前五條記錄,而原始查詢將僅從數據庫直接返回五條記錄。

我的問題是,這兩個查詢之間有任何性能差異?如果是的話哪個更好,爲什麼?

+0

問得好幾個不同的建議 - 我不知道!儘管看看這個答案,你應該能夠應用他們建議的步驟來找出答案。 – chucksmash

+0

哪個答案??? – Haroon

+0

嘿,對不起! [This one](http://stackoverflow.com/a/1074224/341510) – chucksmash

回答

1

我做了我現有的項目快速檢查:

queryset = BlahModel.objects.order_by('?')[:5] 
print queryset.query 

結果是:

SELECT `blah_model`.`id`, `blah_model`.`date` FROM `blah_model` ORDER BY RAND() LIMIT 5; 

所以,它們是相同的。

我也不會太驚訝的結果,因爲Django的ORM是SQL查詢結果與Django的對象之間的直接映射,所以order_by('?')將等於ORDER BY RAND(),連[:5]語句翻譯成mysql中LIMIT(這裏的docdoc)。

1

您看到的任何性能問題都不是因爲django。正如Shang Wang所指出的那樣,Django執行的查詢與原始查詢完全相同。麻煩在於rand()調用。

正如其他地方已經解釋過的,包括像這樣的一些StackOveflow答案:https://stackoverflow.com/a/6911022/267540麻煩是由於必須爲每一行計算一個隨機值的事實。幸運的是,你有一個WHERE子句可以減少行數。隨着數據增長,您的查詢將逐漸變得越來越慢。

此鏈接對如何克服這個問題http://www.warpconduit.net/2011/03/23/selecting-a-random-record-using-mysql-benchmark-results/

+0

避免爲每一行調用'RAND()'是很棘手的。請參閱[我的博客](http://mysql.rjweb.org/doc.php/random)。 –