TokuDB和InnoDB的讀寫分析與比較

來源:互聯網
上載者:User

我們知道,在MySQL單機版本裡面最流行的也是唯一支援全事務的引擎為INNODB。 其特點是資料本身是用B-TREE來組織,資料本身即是龐大的根據主鍵聚簇的B-TREE索引。 所以在這點上,寫入速度就會有些降低,因為要每次寫入要用一次IO來做索引樹的重排。 特別是當資料量本身比記憶體大很多的情況下,CPU本身被磁碟IO糾纏的做不了其他事情了。  這時我們要考慮如何減少對磁碟的IO來排解CPU的處境,那麼如何做呢? (當然,如果資料足夠放到記憶體裡面,這些事情大可不必考慮。)
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=128Mmysql> 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)




相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.