不可否認的,phpBB 本身對於資料庫的使用並沒有達到最高效率... 這點的確必須改進,現在只能盡量有效率的使用 Index 來提升查詢的速度。
全文搜尋是拖慢系統的主因,因為現在搜尋所使用的索引效率不高,往後應該會改用 MySQL 新版的 Full Text Search 功能重新實做,效率會快上不少。\r
Alan_Huang 我沒有這個意思... 程式開發本來就是要交流技術才會有進步的
對了,php 程式也可以在記憶體中儲存編譯後的結果,兩套軟體 APC 和 afterBURNER 都可以做到這樣的功能。配合上 Zend Optimizer 之後,效率並不會輸給 Java Servlet。只是目前瓶頸不在這裡,要裝也懶得弄
<!-- Edit Notice Start -->
<font size=-1>[ 這篇文章在 2001-06-07 20:19 被 Tiberius 編輯過 ]</font><!-- Edit Notice End -->
討論區加速計畫
版主: DearHoney
我自己也在用PHP寫討論區系統,是那種會記錄文章之間彼此回應關係的(phpBB對同一主題下的文章並不紀錄彼此間的回應關係,排列時僅可按照發表時間順序)。兩個多月前的第一個版本,老實說並沒有考慮太多關於資料庫存取效率的問題,後來加入偵錯用的程式碼,才發現在某些頁面裡頭,由於程式寫法與資料表設計上的瑕疵,造成對資料庫發出的query次數多到誇張,最多到一頁超過四十次query,而且發出的query次數會隨著該頁面顯示的文章數目增加而增加(因為在迴圈裡面發出query)。
後來經過一些修正,目前絕大多數頁面發出的query次數都僅有原本的十分之一不到,每一頁在兩次或者三次,不超過四次,也不會隨著顯示的文章篇數一起增加,而且原有的功能都一樣不少。\r
此外正如同程式總監所說,資料表的索引建立非常重要,搭配調整過的 SELECT 語句,其間的效率差異可以差到上百倍。
因此建議可以在phpBB裡面加入偵錯用的程式碼,觀察看看每一頁對資料庫發出的query總次數。此外也可以利用MySQL的 EXPLAIN 語法來檢查對資料庫發出的 SELECT 查詢以及資料表設計與索引是否有達到最佳化。發出的查詢次數越少,每次查詢的方式越佳(join 的資料表少,以及確實利用到索引,EXPLAIN 語法會顯示出這方面的資訊),整體的資料庫查詢效能便可提高。等這一步做完以後,如果還是效能不夠好,再來考慮升級硬體也不遲。
MySQL的 SHOW STATUS 指令會顯示很多有用的相關資訊,可以用來診斷程式對於資料庫的利用效率。
--
以上。個人經驗。
後來經過一些修正,目前絕大多數頁面發出的query次數都僅有原本的十分之一不到,每一頁在兩次或者三次,不超過四次,也不會隨著顯示的文章篇數一起增加,而且原有的功能都一樣不少。\r
此外正如同程式總監所說,資料表的索引建立非常重要,搭配調整過的 SELECT 語句,其間的效率差異可以差到上百倍。
因此建議可以在phpBB裡面加入偵錯用的程式碼,觀察看看每一頁對資料庫發出的query總次數。此外也可以利用MySQL的 EXPLAIN 語法來檢查對資料庫發出的 SELECT 查詢以及資料表設計與索引是否有達到最佳化。發出的查詢次數越少,每次查詢的方式越佳(join 的資料表少,以及確實利用到索引,EXPLAIN 語法會顯示出這方面的資訊),整體的資料庫查詢效能便可提高。等這一步做完以後,如果還是效能不夠好,再來考慮升級硬體也不遲。
MySQL的 SHOW STATUS 指令會顯示很多有用的相關資訊,可以用來診斷程式對於資料庫的利用效率。
--
以上。個人經驗。
我倒是想到一個資料庫透過 ADSL 來存取時的問題。
雖然只要你有錢,要用頻寬大的 ADSL 不是問題,但是撇除 user 端線路與設備上的差異,ADSL 與專線在速度上的差異也是有的,那就是 ADSL 的傳遞時間長。
舉個例子來說,同樣 1MB 檔資料,在頻寬不是問題的情況下,用專線傳輸,也許是 10 秒鐘,但是 ADSL 的話,則是 10.5 秒鐘。也就是說,雖然頻寬都允許,但是因為 delay 現象的關係,總傳輸時間會稍微有差異。
我擔心的就在這裡。以目前我們討論區的畫面來說,一個討論串最長是 15 篇討論,第一次萃取這 15 篇的文字資料以及發言者代號,剩下還有 15 次個別萃取使用者資料的動作,也就是至少要 16 個存取動作才能夠成一個畫面。我擔心的是 ADSL 的延遲時間在總合起來時,會相當驚人。而如果這個現象發生的話,那還不如把討論區搬回家,還是由家裡的電腦來產生整個討論區畫面,畢竟大量且需要快速反應的資料庫存取還是在同一台電腦上最快。
一切要等實做之後才知道了。
雖然只要你有錢,要用頻寬大的 ADSL 不是問題,但是撇除 user 端線路與設備上的差異,ADSL 與專線在速度上的差異也是有的,那就是 ADSL 的傳遞時間長。
舉個例子來說,同樣 1MB 檔資料,在頻寬不是問題的情況下,用專線傳輸,也許是 10 秒鐘,但是 ADSL 的話,則是 10.5 秒鐘。也就是說,雖然頻寬都允許,但是因為 delay 現象的關係,總傳輸時間會稍微有差異。
我擔心的就在這裡。以目前我們討論區的畫面來說,一個討論串最長是 15 篇討論,第一次萃取這 15 篇的文字資料以及發言者代號,剩下還有 15 次個別萃取使用者資料的動作,也就是至少要 16 個存取動作才能夠成一個畫面。我擔心的是 ADSL 的延遲時間在總合起來時,會相當驚人。而如果這個現象發生的話,那還不如把討論區搬回家,還是由家裡的電腦來產生整個討論區畫面,畢竟大量且需要快速反應的資料庫存取還是在同一台電腦上最快。
一切要等實做之後才知道了。
除了搜尋之外,其他所有的 Query 早已做到確實的索引運用... 官方版的 phpBB 資料庫根本無法與之相比,EXPLAIN 的確是好東西
viewtopic.php 現在的瓶頸是在會員資料上, 為了顯示會員的等級、文章數而又不想佔用 posts table 的空間,所以每一篇會員資料都必須下一個 Query 來跑,這是比較辛苦的 ...
phpBB 官方的資料庫設計並不理想,但是 phpBB 卻完全沒有用到 JOIN 等結合資料表的敘述
Marinne 您的網站進不去... 我對您開發的討論區程式有些興趣,可以交流一下嗎?
<!-- Edit Notice Start -->
<font size=-1>[ 這篇文章在 2001-06-09 22:34 被 Tiberius 編輯過 ]</font><!-- Edit Notice End -->
viewtopic.php 現在的瓶頸是在會員資料上, 為了顯示會員的等級、文章數而又不想佔用 posts table 的空間,所以每一篇會員資料都必須下一個 Query 來跑,這是比較辛苦的 ...
phpBB 官方的資料庫設計並不理想,但是 phpBB 卻完全沒有用到 JOIN 等結合資料表的敘述
Marinne 您的網站進不去... 我對您開發的討論區程式有些興趣,可以交流一下嗎?
<!-- Edit Notice Start -->
<font size=-1>[ 這篇文章在 2001-06-09 22:34 被 Tiberius 編輯過 ]</font><!-- Edit Notice End -->
<!-- BBCode Quote Start --><FONT COLOR=GREEN>
viewtopic.php 現在的瓶頸是在會員資料上, 為了顯示會員的等級、文章數而又不想佔用 posts table 的空間,所以每一篇會員資料都必須下一個 Query 來跑,這是比較辛苦的 ...
phpBB 官方的資料庫設計並不理想,但是 phpBB 卻完全沒有用到 JOIN 等結合資料表的敘述
</FONT><!-- BBCode Quote End -->
在選取資料的時候join多個資料表,在很複雜的狀況下會比較慢(而且這種時候索引的使用更重要),然而很多狀況下join多個資料表可以一次取出要用的資料,讓總 query 次數降低,反而能夠提高效率。
我不太清楚phpBB的資料表結構,不過假設每篇文章儲存在 post 資料表中,使用者資料儲存在 user 資料表中(當然每筆 post 紀錄必須有個 foreign key,參照到 user 資料表的 primary key),那麼可以使用 join 來同時把文章資料與該篇文章作者資料一起取出。換句話說,依照 DearHoney 的說法,原本每頁 x 篇文章必須送出 1 + x 次查詢(後面 x 應該是在迴圈裡面送出的),使用 join 的話,就只要一次就可以了,並且與 x 值無關。而且只要索引使用得當,這樣的join並不會慢。
不過如果使用者發表文章數目也是即時計算的話(也就是說 user 資料表裡面並沒有一個欄位用來儲存文章數目),情況會更複雜一些。
至於敝人設計的討論區系統,上線日期還沒到
最主要的麻煩在會員系統完全是另一家公司在負責開發,而且環境和用的語言也不一樣。討論區要搭配的資料庫對方還沒決定(可能是 Oracle 或者 PostgresSQL,也有可能是 MySQL),會員資料存在另一部 Oracle 資料庫(跟討論區的不會是同一部),而且不開放討論區的 PHP 程式直接存取,必須透過該公司提供的 API(一個 Java Class)來取得會員資料。更扯的是會員登入認證系統又是第三家公司在負責,使用 JSP 存取一個 LDAP 伺服器。最令人頭大的是最後這三部分全部都要整合在一起。。。真的讓人傷透腦筋 >_<
---
多言了...
viewtopic.php 現在的瓶頸是在會員資料上, 為了顯示會員的等級、文章數而又不想佔用 posts table 的空間,所以每一篇會員資料都必須下一個 Query 來跑,這是比較辛苦的 ...
phpBB 官方的資料庫設計並不理想,但是 phpBB 卻完全沒有用到 JOIN 等結合資料表的敘述
</FONT><!-- BBCode Quote End -->
在選取資料的時候join多個資料表,在很複雜的狀況下會比較慢(而且這種時候索引的使用更重要),然而很多狀況下join多個資料表可以一次取出要用的資料,讓總 query 次數降低,反而能夠提高效率。
我不太清楚phpBB的資料表結構,不過假設每篇文章儲存在 post 資料表中,使用者資料儲存在 user 資料表中(當然每筆 post 紀錄必須有個 foreign key,參照到 user 資料表的 primary key),那麼可以使用 join 來同時把文章資料與該篇文章作者資料一起取出。換句話說,依照 DearHoney 的說法,原本每頁 x 篇文章必須送出 1 + x 次查詢(後面 x 應該是在迴圈裡面送出的),使用 join 的話,就只要一次就可以了,並且與 x 值無關。而且只要索引使用得當,這樣的join並不會慢。
不過如果使用者發表文章數目也是即時計算的話(也就是說 user 資料表裡面並沒有一個欄位用來儲存文章數目),情況會更複雜一些。
至於敝人設計的討論區系統,上線日期還沒到
最主要的麻煩在會員系統完全是另一家公司在負責開發,而且環境和用的語言也不一樣。討論區要搭配的資料庫對方還沒決定(可能是 Oracle 或者 PostgresSQL,也有可能是 MySQL),會員資料存在另一部 Oracle 資料庫(跟討論區的不會是同一部),而且不開放討論區的 PHP 程式直接存取,必須透過該公司提供的 API(一個 Java Class)來取得會員資料。更扯的是會員登入認證系統又是第三家公司在負責,使用 JSP 存取一個 LDAP 伺服器。最令人頭大的是最後這三部分全部都要整合在一起。。。真的讓人傷透腦筋 >_<
---
多言了...