MySql各引擎特点和性能测试
Mysql為什么要分很多引擎:
MySQL中的數據用各種不同的技術存儲在文件(或者內存)中。這些技術中的每一種技術都使用不同的存儲機制、索引技巧、鎖定水平并且最終提供廣泛的不同的功能和能力。通過選擇不同的技術,你能夠獲得額外的速度或者功能,從而改善你的應用的整體功能。
引擎是真對于表的,在創建表的時候可以直接指定使用的引擎,例如:
也可以通過配置文件里直接修改默認引擎:
?
加上這條(然后重啟服務)
default-storage-engine=InnoDB
之后可以通過 show create table 表名 來查詢表使用的引擎
?
如果本地是docker的話,一件部署安裝mysql可以直接用下面命令
docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d -v /tmp/mysqldata/:/var/lib/mysql/ mysql
?
登陸mysql查看本地支持的引擎:
SHOW ENGINES;
?
1.InnoDB默認引擎
? ? Innodb引擎提供了對數據庫ACID事務的支持,并且實現了SQL標準的四種隔離級別,關于數據庫事務與其隔離級別的內容請見數據庫事務與其隔離級別這類型的文章。該引擎還提供了行級鎖和外鍵約束,它的設計目標是處理大容量數據庫系統,它本身其實就是基于MySQL后臺的完整數據庫系統,MySQL運行時Innodb會在內存中建立緩沖池,用于緩沖數據和索引。但是該引擎不支持FULLTEXT類型的索引,而且它沒有保存表的行數,當SELECT COUNT(*) FROM TABLE時需要掃描全表。當需要使用數據庫事務時,該引擎當然是首選。由于鎖的粒度更小,寫操作不會鎖定全表,所以在并發較高時,使用Innodb引擎會提升效率。但是使用行級鎖也不是絕對的,如果在執行一個SQL語句時MySQL不能確定要掃描的范圍,InnoDB表同樣會鎖全表,InnoDB給MySQL提供了具有提交、回滾和崩潰恢復能力的事務安全(ACID兼容)存儲引擎。
原理:
? ? 是B+Treee索引結構。Innodb的索引文件本身就是數據文件,即B+Tree的數據域存儲的就是實際的數據,這種索引就是聚集索引。這個索引的key就是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。InnoDB的輔助索引數據域存儲的也是相應記錄主鍵的值而不是地址,所以當以輔助索引查找時,會先根據輔助索引找到主鍵,再根據主鍵索引找到實際的數據。所以Innodb不建議使用過長的主鍵,否則會使輔助索引變得過大。建議使用自增的字段作為主鍵,這樣B+Tree的每一個結點都會被順序的填滿,而不會頻繁的分裂調整,會有效的提升插入數據的效率。
?
2.MyIsam引擎
? ? 不支持事務的設計,但是并不代表著有事務操作的項目不能用MyIsam存儲引擎,可以在service層進行根據自己的業務需求進行相應的控制,不支持外鍵的表設計,查詢速度很快,如果是多查詢,少修改的情況下建議使用,MyISAM極度強調快速讀取操作,MyIASM中存儲了表的行數,于是SELECT COUNT(*) FROM TABLE時只需要直接讀取已經保存好的值而不需要進行全表掃描。如果表的讀操作遠遠多于寫操作且不需要數據庫事務的支持,那么MyIASM也是很好的選擇。不能在表損壞后恢復數據。(是不能主動恢復)
原理:
? ? MyISAM索引結構: MyISAM索引用的B+ tree來儲存數據,MyISAM索引的指針指向的是鍵值的地址,地址存儲的是數據。B+Tree的數據域存儲的內容為實際數據的地址,也就是說它的索引和實際的數據是分開的,只不過是用索引指向了實際的數據,這種索引就是所謂的非聚集索引。
?
3.Mrg_Myisam引擎
? ? 是一個相同的可以被當作一個來用的MyISAM表的集合。“相同”意味著所有表同樣的列和索引信息。他將MyIsam引擎的多個表聚合起來,但是他的內部沒有數據,真正的數據依然是MyIsam引擎的表中,但是可以直接進行查詢、刪除更新等操作。
測試代碼如下(創建兩個user表,然后聚合一下)
CREATE TABLE IF NOT EXISTS user1 ( ?id int(11) NOT NULL ,name varchar(50) DEFAULT NULL, ?PRIMARY KEY (id) ?) ENGINE=MyISAM ?DEFAULT CHARSET=utf8 ; ?CREATE TABLE IF NOT EXISTS user2 ( ?id int(11) NOT NULL ,name varchar(50) DEFAULT NULL, ?PRIMARY KEY (id) ?) ENGINE=MyISAM ?DEFAULT CHARSET=utf8 ; ?INSERT INTO user1 (id,name) VALUES(1,'00000'); ?INSERT INTO user2 (id,name) VALUES(1,'xxxxx');CREATE TABLE IF NOT EXISTS alluser ( ?id int(11) NOT NULL , ?name varchar(50) DEFAULT NULL, ?PRIMARY KEY (id)) ENGINE=MRG_MYISAM ?DEFAULT CHARSET=utf8UNION=(user1,user2) ?;SELECT a.*,b.* FROM user1 a ,user2 b;SELECT * FROM alluser;?
4.Memory引擎
? ? 所有的數據都是跑在內存里,適合場景是中間數據緩存的情況,讀寫速度很高。最后性能測試里面有這個。
5.Blackhole引擎
? ? 任何寫入到此引擎的數據均會被丟棄掉, 不做實際存儲;Select語句的內容永遠是空。
他會丟棄所有的插入的數據,服務器會記錄下Blackhole表的日志,所以可以用于復制數據到備份數據庫。
使用場景:
1)驗證dump file語法的正確性
2)以使用blackhole引擎來檢測binlog功能所需要的額外負載
3)充當日志服務器
?
6.Archive引擎
? ? 以zlib對表數據進行壓縮,磁盤I/O更少,數據存儲在ARZ為后綴的文件中。只支持insert和select操作(支持行級所和緩沖區,可以實現高并發的插入)
只允許在自增ID列上加索引。Archive表比MyISAM表要小大約75%,比支持事務處理的InnoDB表小大約83%。當數據量非常大的時候Archive的插入性能表現會較MyISAM為佳。下面是速度測試
同樣數量級10W,生成的數據庫文件大小比較(跟CSV引擎對比)
?
?
7.CSV引擎
最大亮點,用CSV類型的文件進行存儲。
直接上操作
然后去找本地數據庫文件看下:
?
最后對如上7個引擎中的六個進行了同環境下的性能測試(insert),用于對比實際情況下不同引擎的insert操作性能對比,可能結果跟想象的不一樣。
我是在相同配置環境下操作的,操作數據10W,但是注意,我磁盤是SDD.
? ? 為什么會產生上面那樣的數據?我的理解是,很多引擎的針對不同情況的優化都是針對磁盤的,這個磁盤是機械硬盤,主要處理頻繁隨機讀寫導致的磁盤尋道。但是SSD上并不存在尋道的概念,這回讓很多算法展示出尷尬的一面,甚至導致因為操作過于高端(去處理尋道問題),導致反而浪費了很多時間。
?
下面附上面提到的所有相關代碼(包括壓力測試):
----InnoDB性能測試相關-----create table testInnoDB(id int unsigned primary key auto_increment,name varchar(20) not null)engine=innodb ;delimiter $$drop procedure if exists ptestmyisam;create procedure ptestmyisam()begindeclare pid int ;set pid = 100000;while pid>0doinsert into testInnoDB(name) values(concat("val:", pid));set pid = pid-1;end while;end $$call ptestmyisam() $$delimiter ;----MyIsam性能測試相關-----create testMyIsam( ?id int unsigned primary key auto_increment, ?name varchar(20) not null ?)engine=myisam ;delimiter $$drop procedure if exists ptestmyisam;create procedure ptestmyisam()begindeclare pid int ;set pid = 100000;while pid>0doinsert into testMyIsam(name) values(concat("val:", pid));set pid = pid-1;end while;end $$call ptestmyisam() $$delimiter ;----Memory性能測試相關-----create table testMemory( ?id int unsigned primary key auto_increment, ?name varchar(20) not null ?)engine=memory ;delimiter $$drop procedure if exists ptestmyisam;create procedure ptestmyisam()begindeclare pid int ;set pid = 100000;while pid>0doinsert into testMemory(name) values(concat("val:", pid));set pid = pid-1;end while;end $$call ptestmyisam() $$delimiter ;----Blackhole性能測試相關-----create table testBlackhole( ?id int unsigned primary key auto_increment, ?name varchar(20) not null ?)engine=blackhole ;delimiter $$drop procedure if exists ptestmyisam;create procedure ptestmyisam()begindeclare pid int ;set pid = 100000;while pid>0doinsert into testBlackhole(name) values(concat("val:", pid));set pid = pid-1;end while;end $$call ptestmyisam() $$delimiter ;----CSV性能測試相關-----create table testCSV(id int unsigned not null,name varchar(20) not null)engine=CSV ;delimiter $$drop procedure if exists ptestmyisam;create procedure ptestmyisam()begindeclare pid int ;set pid = 100000;while pid>0doinsert into testCSV(id,name) values(pid,concat("val:", pid));set pid = pid-1;end while;end $$call ptestmyisam() $$delimiter ;----Archive性能測試相關-----create table testArchive(id int unsigned primary key auto_increment, ?name varchar(20) not null)engine=Archive ;delimiter $$drop procedure if exists ptestmyisam;create procedure ptestmyisam()begindeclare pid int ;set pid = 100000;while pid>0doinsert into testArchive(name) values(concat("val:", pid));set pid = pid-1;end while;end $$call ptestmyisam() $$delimiter ;----Mrg_Myisam相關-----CREATE TABLE IF NOT EXISTS user1 ( ?id int(11) NOT NULL ,name varchar(50) DEFAULT NULL, ?PRIMARY KEY (id) ?) ENGINE=MyISAM ?DEFAULT CHARSET=utf8 ; ?CREATE TABLE IF NOT EXISTS user2 ( ?id int(11) NOT NULL ,name varchar(50) DEFAULT NULL, ?PRIMARY KEY (id) ?) ENGINE=MyISAM ?DEFAULT CHARSET=utf8 ; ?INSERT INTO user1 (id,name) VALUES(1,'00000'); ?INSERT INTO user2 (id,name) VALUES(1,'xxxxx');CREATE TABLE IF NOT EXISTS alluser ( ?id int(11) NOT NULL , ?name varchar(50) DEFAULT NULL, ?PRIMARY KEY (id)) ENGINE=MRG_MYISAM ?DEFAULT CHARSET=utf8UNION=(user1,user2) ?;SELECT a.*,b.* FROM user1 a ,user2 b;SELECT * FROM alluser;?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的MySql各引擎特点和性能测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis批量操作及性能分析
- 下一篇: Docker 底层实现