2012-12-14 37 views
1

爲簡單起見,我將該問題轉換爲員工/工資問題。加速SQL語句以查找導致設置記錄數的條件參數

擁有僱員記錄emp如:

| id | salary (in 1000s) | 

鑑於許多「num」,找到工資「sal」在哪裏(統計類似於曲線下面積問題)接收salary<=sal>=num員工人數。 我們使用Python和SQLite,但問題是不特定對他們說:

我做了以下(天真的原料溶液):

num = some_num 
sal = 1000 # starting miminmum value 
count = 0 
while count < num: 
    sql = 'select count(*) from (select 1 from emp where salary<=? limit ?)' 
    # using limit so that we don't keep counting more than num - might help (?) 
    (count,) = cursor.execute(sql, (sal, num)).next() # using apsw sqlite adapter 
    sal += 1000 

print sal 

我們怎樣才能使這個更有效? (算法上使用標準的SQL或等價物,但不使用給定系統的怪癖)

或者:可以通過在記錄中添加額外的字段來提高效率,這些字段可以保持最新的插入/更新操作沒有太多的開銷?

回答

1

如果您使用的是準備好的語句,我相信您可以將準備步驟移出循環以使其更快。

sql = 'select count(*) from (select 1 from emp where salary<=? limit ?)' 
# using limit so that we don't keep counting more than num - might help (?) 
while count < num: 
    (count,) = cursor.execute(sql, (sal, num)) 
    sal += 1000 

如果您想進一步提高性能和您的數據庫的大小是相當小的,你可以在整個數據加載到一個數組,做你的操作。

我認爲如果先按薪水對數組進行排序,則可以進一步優化。之後,您可以執行二進制搜索到<條件翻轉的位置,並將該位置的索引+1作爲計數。

編輯

的解決方案是簡單的比它的外觀。如果記錄由薪酬進行排序,則#num'th記錄的薪水將是需要的答案,所以這成爲selecting the n'th row一個問題:

num = some_num 
sql = 'select salary from emp order by salary limit 1 offset ?' 
(sal,) = cursor.execute(sql, (num-1,)).next() 
print sal 
+0

感謝。這可能對我有點幫助,但我們仍然在做很多計數操作,而且如果薪水有很大差距,那麼許多操作都是不必要的。 –

+0

@BaselShishani你能讀我的編輯嗎?看起來像解決方案比看起來簡單.. –

+0

是的,如果我們按工資排序並選擇num_th記錄,那麼低於該工資值(包括)的總記錄將等於num。 –