1. 可以把INNODB 個PAGE增大?(默認16KB)但是增大也就帶來了一些缺陷。 比如,對磁盤進行CHECKPOINT的時間將延後。
2. 把日誌文件放到更快速的磁盤上?比如SSD?
其實這時,我們可以考慮用另外一個知名的引擎TokuDB。 誰叫MySQL 天生支持隨意可插拔呢!
TokuDB 其實本身數據存儲用到了B-TREE的變形版本Fractal-Tree。 Fractal-Tree 也就是在B-Tree原來的非葉子節點增加了一個緩存,無論對這個樹怎麼操作,都是一個模式:即父親節點的緩存滿了,就流淌到兒子節點,然後兒子節點的緩存滿了後,再次流淌到孫子節點等等一系列最後到了葉子節點,然後等到葉子節點的PAGE足夠大的時候,進行CHECK POINT。當然不管如何做緩存,每次事務後,還是得首先刷新到REDO 日誌,要不數據一致性就很難保證了。
接下來,這裏測試下同樣的環境InnoDB和TokuDB的性能差異。當然,我沒有做壓力測試,只是簡單的手動執行了幾次SQL而已。
(5.6.10-enterprise-commercial-advanced-log MySQL Enterprise Server - Advanced Edition (Commercial))
用來導入的文件大概爲35M。
1. INNODB.
對應的參數:
innodb_buffer_pool_size=32M
bulk_insert_buffer_size=20M
query_cache_size = 0
導入性能:(InnoDB在這裏慢在CPU一直忙於IO置換。)
mysql> load data infile '/tmp/t3_push.csv' into table t3_push;
Query OK, 955527 rows affected (30 min 44.03 sec)
Records: 955527 Deleted: 0 Skipped: 0 Warnings: 0
讀性能:(讀的性能還是很好的,這裏用到5.6的ICP以及MRR特性。)
mysql> select count(*) from t3_push where rank1 < 20 and rank2 < 30;
+----------+
| count(*) |
+----------+
| 49 |
+----------+
1 row in set (0.06 sec)
調大
innodb_buffer_pool=128M
mysql> load data infile '/tmp/t3_push.csv' into table t3_push;
Query OK, 955527 rows affected (38.72 sec)
Records: 955527 Deleted: 0 Skipped: 0 Warnings: 0
調大後,其實導入性能還是不錯的。
2. TokuDB.
(5.5.30-tokudb-7.1.0-e-log TokuDB Enterprise Server (GPL) )
對應的參數:
tokudb_cache_size=32M
tokudb_loader_memory_size=20M
query_cache_size = 0
寫性能:(這裏IO次數很少,所以導入速度很快。)
mysql> load data infile '/tmp/t3_push.csv' into table t3_push;
Query OK, 955527 rows affected (19.73 sec)
Records: 955527 Deleted: 0 Skipped: 0 Warnings: 0
讀性能:(讀的速度比INNODB稍微慢了些。)
mysql> select count(*) from t3_push where rank1 < 20 and rank2 < 30;
+----------+
| count(*) |
+----------+
| 49 |
+----------+
1 row in set (0.54 sec)
mysql> select count(*) from t3_push where rank1 < 200 and rank2 < 300;
+----------+
| count(*) |
+----------+
| 5759 |
+----------+
1 row in set (4.13 sec)
但是TokuDB可以給二級索引變聚簇,所以這點上如果只讀的話,還是會比InnoDB快。
給列rank2 加聚簇索引,
mysql> alter table t3_push add clustering index idx_rank2(rank2);
Query OK, 0 rows affected (6.79 sec)
Records: 0 Duplicates: 0 Warnings: 0
現在所有的基於索引idx_rank2 的查詢都是瞬間的。
mysql> select count(*) from t3_push where rank1 < 20 and rank2 < 30;
+----------+
| count(*) |
+----------+
| 49 |
+----------+
1 row in set (0.00 sec)
mysql> select count(*) from t3_push where rank1 < 200 and rank2 < 300;
+----------+
| count(*) |
+----------+
| 5759 |
+----------+
1 row in set (0.01 sec)