11 月 20 2009
一些增進 MySQL 效能的 tips
幾天前,跟 Solaris 叔叔 談到 MySQL 的 ENUM,回家後上網找了些資料,剛好找出了一些使用 MySQL 時,與效能有關的 tips。
稍微整理過後,放在這裡:
- 善用 EXPLAIN SELECT 分析 SQL statement,以下列舉狀態解讀:
EQ_REF 一對一比對 REF 一對多比對 RANGE 特定範圍的資料會被傳回 INDEX 使用 INDEX 裡的資料 ALL 對整個 TABLE 作掃瞄(最差) - 善用 INDEX,以這個 SQL statement 為例:
SELECT `col_a` FROM `table_a` LEFT JOIN `table_b` ON `table_a`.`col_b` = `table_b`.`col_c` WHERE `col_d` = ....; -- SELECT 的欄位不需 INDEX,ex: `col_a`。 -- JOIN 的欄位需要 INDEX,ex: `table_a`.`col_b` 與 `table_b`.`col_c`。 -- WHERE 的欄位需要 INDEX,ex: `col_d`。
- 儘量使用固定大小的欄位,MyISAM 搜尋固定大小欄位比較快;也就是說,能用 CHAR 就別用 VARCHAR。
- 儘量將欄位指定為 NOT NULL。
- ENUM 格式的欄位,資料處理速度很快(實測結果在這)。
- 不要取不需要的資料,下面這種語法就是不好的例子:
SELECT * ...
- 把 BLOB 與 TEXT 拆開,減少 MySQL 開啟單一大檔(table 資料檔案過大)的機會。
- JOIN 用的欄位資料格式最好是相同的,以免 MySQL 作 FULL TABLE SCAN。
- 使用 LIKE 時,避免把 % 放在字串開頭,以免 INDEX 利用率不佳。
-- 下列這種語法無法利用 INDEX SELECT ... WHERE `col` LIKE '%string%'; -- 下列這種語法會利用 INDEX SELECT ... WHERE `col` LIKE 'string%';
- 注意 WHERE 子句內的運算式。
-- 下列這種語法會使用 INDEX,速度快。 SELECT ... WHERE `col` < 100 / 10; -- 下列這種語法會導致 FULL TABLE SCAN,速度慢。 SELECT ... WHERE `col` * 10 < 100;
9 月 27 2013
[PHP] HTTP 連線的資料共用
我相信有許多 Web 應用程式開發者與我類似,常常想辦法預存一些經常存取、變動頻率不高的資料,提昇程式效能。
透過這類的資料預存,可以降低資料庫存取頻率,並減少 server 的 file I/O 次數。
在 .Net 與 JAVA 的領域,程式語言都提供了相關的物件/變數,讓 Web 應用程式儲存資料,而該應用程式的所有連線使用者皆可以存取。
.Net 用的是 System.Web.Caching.Cache;JAVA Servlet 是 javax.servlet.ServletContext,而 JSP 的 Application 物件便是其實作。
但在常見的環境(eg. Apache HTTPD w/MPM prefork + mod_php),也沒有額外的模組(eg. APC、memcache),PHP 難以提供這種物件/變數讓人使用,開發者只能硬幹。 :p
因為 COOKIE 的 size 有限,在 PHP 大概只能用 SESSION 硬幹。
我是這樣做的…
存入/更新:
讀取:
因為所有程式都能存取 session 內的資料,不建議在 session 內儲存私密/機密資料。
若要避免資料不小心被同一台 server 的其他程式,可以加上 session_name() 作區隔。
By Joe Horn • PHP 0 • Tags: javax.servlet.ServletContext, performance, PHP, session, System.Web.Caching.Cache