robot
最新文章(10)
Mqskit 和其它相關工具
CPython 的 GC 二、三事
寫 Mecurial Extension 是件快樂的事!
Mozilla 台灣辨公室徵人啟事
關於 Apple 的兩項專利
core dump 之前的 frame
怎麼發出 beep 聲?
先承認你要找的是奴才吧!
程式碼要清的多乾淨?
FreeBSD 的 Thread-Local Storage 實作
首頁
新編
最新留言
Entries RSS
重要關鍵字(10)
coding (122)
Python (93)
FreeBSD (71)
WEB (61)
URL (48)
hardware (46)
javascript (36)
Linux (34)
blog (30)
C++ (16)
所有關鍵字
新增 URL
改善 Python 加 SQLite 程式的效能
by thinker
2 Columns
關鍵字:
Python
應該許多人發現,這陣子敝網站的效能很差。主要是因為,我換了機器,而且愈換愈差,尤其是從 hard disk 轉到 CF 。而 CPU 換成 Pentium 166MHz 等級,則和之前一樣。新機器的好處是,沒有風扇、沒有硬碟,所以是零噪音,而且低耗電。 但,轉換之後,速度實在慢到不行。在撐了一段時間之後,我終於受不了,著手解決這個問題。一開始,我讓 $GinGin$ 改採 mez_xml ,並改成 fastcgi 。雖然有明顯的改進,但依然不足。於是,我打算進一步的做改善。改進不能漫無目的,盲目的進行修改,往往只是徒勞無功。首先,先以 linkname:hotshot http://docs.python.org/lib/module-hotshot.html 為 $GinGin$ 診斷,找出效能頻頸。於是得到下面的報告: {{{#!raw 570 function calls (568 primitive calls) in 5.412 CPU seconds Ordered by: internal time, call count List reduced from 64 to 20 due to restriction <20> ncalls tottime percall cumtime percall filename:lineno(function) 1 2.390 2.390 2.390 2.390 /usr/local/lib/python2.5/site-packages/$GinGin$/$GinGin$_db.py:536(get_hot_keywords) 1 1.725 1.725 1.758 1.758 /usr/local/lib/python2.5/site-packages/$GinGin$/$GinGin$_db.py:240(get_last_abstracts) 1 0.876 0.876 0.876 0.876 /usr/local/lib/python2.5/site-packages/$GinGin$/$GinGin$_db.py:203(get_last_docs) 108 0.092 0.001 0.127 0.001 /usr/local/lib/python2.5/site-packages/mez_xml/tools.py:126(_esc_text) 15 0.055 0.004 0.073 0.005 /usr/local/lib/python2.5/_strptime.py:297(strptime) 15 0.055 0.004 0.175 0.012 /usr/local/lib/python2.5/site-packages/$GinGin$/templates/rssfeed.py:41(temp) 108 0.035 0.000 0.035 0.000 ............ }}} 很明顯的,問題出現在 $database$ 的 access (get_hot_keywords/get_last_abstracts/get_last_docs)。於我檢查了這些 query ,發覺 $SQLite$ 針對某欄位排序後輸出,效率很低。於是,我為該欄位做了 index 。然後再測,相同的 query ,反應速度由數秒變成瞬間。 {{{#!raw CREATE INDEX last_docs on docs (pdate desc); }}} 後來又發覺, view 的使用,造成大量的計算。於是將 view 拿掉,建一個實體的 table ,並使用 triger 進行更新。這樣我才能不動一行程式碼,就能保持 table 如同 view 一樣,隨時和 source table 同步、一致。 {{{#!raw CREATE TRIGGER delete_docs delete on kws_docs begin update hot_kws set num = num - 1 where $keyword$ = (select $keyword$ from keywords where kw_id = old.kw_id); end; CREATE TRIGGER delete_urls delete on kws_urls begin update hot_kws set num = num - 1 where $keyword$ = (select $keyword$ from keywords where kw_id = old.kw_id); end; CREATE TRIGGER update_keywords insert on kws_docs begin update hot_kws set num = num + 1 where $keyword$ = (select $keyword$ from keywords where kw_id = new.kw_id); end; CREATE TRIGGER update_urls insert on kws_urls begin update hot_kws set num = num + 1 where $keyword$ = (select $keyword$ from keywords where kw_id = new.kw_id); end; }}} 這是我頭一次在 $SQLite$ 上使用 index 和 trigger ,得到的效果令人滿意。如果能移到 FON 上面,是否一樣讓人滿意?? 雖然只是在 schema 上的小小改進,卻有天與地的差別。注意一下 SQL 的使用,或許會有意想不到的結果。但也不要過度的追求,反而浪費寶貴的時間。
最後更新時間: 2008-06-17 17:08:02 CST |
引用
查詢:
COMMENTS: