2013-02-05 39 views
1

我有兩個表,companyinvestment,我需要在公司表中包含一列,其中包含每家公司的投資數量。優化在每個行整個表上聚合的更新命令

順便說一下這是一個sqlite數據庫。

我嘗試以下查詢:

UPDATE company SET numlinks = (SELECT count(*) 
            FROM investment 
            WHERE investment.company_name = company.name); 

我敢肯定查詢是正確的。如果我爲單個公司運行該行,則該行會被正確更新。但鑑於我有超過300K行,查詢開始運行,似乎需要一段時間。

當運行它單個公司的.timer ON命令,所使用的CPU爲約0.03(我不知道單位,我猜它在幾秒鐘內)

,我怎麼能做出這樣快的任何想法?

+0

你需要一個* pure * SQL解決方案嗎?還是你使用「前端」編程語言? – Barranka

+0

這實際上並不適用於Web應用程序,但我可以在Python中使用某些東西。爲什麼這會更有效率? – leonsas

+0

我認爲SQLite的限制(例如,你不能在'update'語句中使用'join')會使它變得複雜......你需要在你的where條件下輸入每一個公司的id在你的子查詢和你的'update'語句中)...爲了方便起見,我會用前端解決方案來做,而不是直接在SQLite中,但這只是我 – Barranka

回答

1

這是最簡單的解決方案。

alter table company 
drop column numlinks 

一個數據庫標準化的首要原則是不存儲的計算值。當您想要顯示鏈接的數量時,請在需要時查詢。

select company.name, other_stuff, count(*) links 
from company join investment on company.name = investment.company_name 
group by company.name, other_stuff 

順便說一句,與當前的設計,你有麻煩了,如果兩家公司擁有相同的名稱。這就是爲什麼名稱字段很少用於識別記錄的原因。

如果在理解這個答案時遇到困難,我已經聽說過關於這本書「數據庫設計僅僅是人類」的好消息。

+0

鑑於我會經常使用這種計算,我決定將它存儲起來會很有用。感謝您幫助我堅持良好的做法。 – leonsas

1

你想要做的是計算摘要,然後將它們加入到更新語句中。不幸的是,SQLite不支持連接(here),除非通過這種相關的子查詢語法。使這個速度

一種方法是創建一個臨時表:

select company_name, count(*) as cnt 
from investment 
group by company_name 

然後做同樣的事情與此表:

set numlinks = (select cnt from TemporaryTable) 

的性能優勢是雙重的。首先,您不必爲每一行重新進行計算。更重要的是,您可以在company_name上創建索引,顯着加快查詢速度。