Mar 08

我利用前兩天的空閒時間寫了個 PHP 的小程式,運用 PHP 的 PDO 元件,對 MySQL 進行小測試。

Server 作業系統與硬體:

  • 作業系統:FreeBSD 8.0-RELEASE
  • CPU:Intel(R) Pentium(R) 4 CPU 3.00GHz (3042.62-MHz 686-class CPU),Hyper-Threading 開啟
  • RAM:2G DDR2 800
  • 放資料庫的 HDD:WDC WD800JB-00JJA0,UDMA 100

MySQL 5.1.44 的設定(/etc/my.cnf):

# defult setting (maybe changed)
key_buffer_size = 128M
max_allowed_packet = 4M
table_open_cache = 4096
sort_buffer_size = 1M
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M

# added for tunning by Joe Horn
skip-name-resolve
connect_timeout = 60
join_buffer_size = 1M
max_connect_errors = 10000
max_connections = 100
max_heap_table_size = 1G
query_cache_size = 16M
slave_net_timeout = 30
sync_binlog=1
thread_cache_size = 512
thread_concurrency = 8
tmp_table_size = 1G
table_definition_cache = 512
# choose one ( depend on query amount )
#concurrent_insert=2
low_priority_updates=1

這台機器跑 Super Smack 的結果:

# super-smack -d mysql update-select.smack 80 1000
Query Barrel Report for client smacker
connect: max=14ms  min=1ms avg= 4ms from 80 clients
Query_type      num_queries  max_time  min_time  q_per_s
select_index    80000        101       6         717.91
update_index    80000        108       1         717.91

我用測試程式產生了一百萬筆資料的 MyISAM table,各種測試各循環 1000 次,產生如下的測試結果(後面的數字單位是秒):

SELECT BY PK_COL WITH_QUERY_CACHE:              0.058
SELECT BY PK_COL WITHOUT_QUERY_CACHE:           0.062
SELECT BY PK_COL LIMIT WITH_QUERY_CACHE:        0.058
SELECT BY PK_COL LIMIT WITHOUT_QUERY_CACHE:     0.062
SELECT BY UNIQUE_COL WITH_QUERY_CACHE:          0.058
SELECT BY UNIQUE_COL WITHOUT_QUERY_CACHE:       0.062
SELECT BY UNIQUE_COL LIMIT WITH_QUERY_CACHE:    0.058
SELECT BY UNIQUE_COL LIMIT WITHOUT_QUERY_CACHE: 0.062
SELECT BY INDEX_COL WITH_QUERY_CACHE:           0.058
SELECT BY INDEX_COL WITHOUT_QUERY_CACHE:        0.061
SELECT BY INDEX_COL LIMIT WITH_QUERY_CACHE:     0.058
SELECT BY INDEX_COL LIMIT WITHOUT_QUERY_CACHE:  0.063
SELECT BY COL WITH_QUERY_CACHE:                 0.786
SELECT BY COL WITHOUT_QUERY_CACHE:              0.063
SELECT BY COL LIMIT WITH_QUERY_CACHE:           0.059
SELECT BY COL LIMIT WITHOUT_QUERY_CACHE:        0.062
UPDATE BY PK_COL WITH_QUERY_CACHE:              1.139
UPDATE BY PK_COL WITHOUT_QUERY_CACHE:           1.199
UPDATE BY PK_COL LIMIT WITH_QUERY_CACHE:        0.125
UPDATE BY PK_COL LIMIT WITHOUT_QUERY_CACHE:     0.142
UPDATE BY UNIQUE_COL WITH_QUERY_CACHE:          2.734
UPDATE BY UNIQUE_COL WITHOUT_QUERY_CACHE:       1.203
UPDATE BY UNIQUE_COL LIMIT WITH_QUERY_CACHE:    0.147
UPDATE BY UNIQUE_COL LIMIT WITHOUT_QUERY_CACHE: 0.163
UPDATE BY INDEX_COL WITH_QUERY_CACHE:           1.183
UPDATE BY INDEX_COL WITHOUT_QUERY_CACHE:        1.063
UPDATE BY INDEX_COL LIMIT WITH_QUERY_CACHE:     0.138
UPDATE BY INDEX_COL LIMIT WITHOUT_QUERY_CACHE:  0.154
UPDATE BY COL WITH_QUERY_CACHE:                 4704.859
UPDATE BY COL WITHOUT_QUERY_CACHE:              4641.191
UPDATE BY COL LIMIT WITH_QUERY_CACHE:           0.156
UPDATE BY COL LIMIT WITHOUT_QUERY_CACHE:        0.167

根據測試結果,大概可以看到出以下幾個要點:

  1. 根據第 21 行與 22 行的差異看來,MySQL Query cache 還是有點用處,不過效用不大。
  2. 根據第 13 行與第 29 行的結果看來,有沒有設定 Primary Key、UNIQUE、INDEX 的影響不小。
  3. 根據 UPDATE 語法的測試結果看來,有沒有 LIMIT 頗重要。

Technorati Tags: , , , , , , , , ,

Tags: , , , , , , , , ,
(Visited 213 times)
Nov 20

幾天前,跟 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;

Technorati Tags: , , , , , , , , , ,

Tags: , , , , , , , , , ,
(Visited 3443 times)