剛學習數據庫,本來沒有引擎的概念,書上遇到了,於是網上找了一篇文章充實一下。
出處:http://blog.csdn.net/wangyang1354/article/details/50740041
經常用MySQL數據庫,但是,你在用的時候注意過沒有,數據庫的存儲引擎,可能有注意但是並不清楚什麼意思,可能根本沒注意過這個問題,使用了默認的數據庫引擎,當然我之前屬於後者,後來成了前者,然後就有了這篇博文啦,希望可以幫助部分人瞭解MySQL引擎的一些特性。
存儲引擎概念
MySQL中的數據用各種不同的技術存儲在文件(或者內存)中。這些技術中的每一種技術都使用不同的存儲機制、索引技巧、鎖定水平並且最終提供廣泛的不同的功能和能力。通過選擇不同的技術,你能夠獲得額外的速度或者功能,從而改善你的應用的整體功能。
有哪些存儲引擎
存儲引擎主要有: 1. MyIsam , 2. Mrg_Myisam, 3. Memory, 4. Blackhole, 5. CSV, 6. Performance_Schema, 7. Archive, 8. Federated , 9 InnoDB
-
mysql> show engines\G
-
*************************** 1. row ***************************
-
Engine: MyISAM
-
Support: YES
-
Comment: MyISAM storage engine
-
Transactions: NO
-
XA: NO
-
Savepoints: NO
-
*************************** 2. row ***************************
-
Engine: MRG_MYISAM
-
Support: YES
-
Comment: Collection of identical MyISAM tables
-
Transactions: NO
-
XA: NO
-
Savepoints: NO
-
*************************** 3. row ***************************
-
Engine: MEMORY
-
Support: YES
-
Comment: Hash based, stored in memory, useful for temporary tables
-
Transactions: NO
-
XA: NO
-
Savepoints: NO
-
*************************** 4. row ***************************
-
Engine: BLACKHOLE
-
Support: YES
-
Comment: /dev/null storage engine (anything you write to it disappears)
-
Transactions: NO
-
XA: NO
-
Savepoints: NO
-
*************************** 5. row ***************************
-
Engine: CSV
-
Support: YES
-
Comment: CSV storage engine
-
Transactions: NO
-
XA: NO
-
Savepoints: NO
-
*************************** 6. row ***************************
-
Engine: PERFORMANCE_SCHEMA
-
Support: YES
-
Comment: Performance Schema
-
Transactions: NO
-
XA: NO
-
Savepoints: NO
-
*************************** 7. row ***************************
-
Engine: ARCHIVE
-
Support: YES
-
Comment: Archive storage engine
-
Transactions: NO
-
XA: NO
-
Savepoints: NO
-
*************************** 8. row ***************************
-
Engine: FEDERATED
-
Support: NO
-
Comment: Federated MySQL storage engine
-
Transactions: NULL
-
XA: NULL
-
Savepoints: NULL
-
*************************** 9. row ***************************
-
Engine: InnoDB
-
Support: DEFAULT
-
Comment: Supports transactions, row-level locking, and foreign keys
-
Transactions: YES
-
XA: YES
-
Savepoints: YES
-
9 rows in set (0.00 sec)
存儲引擎的主要特性
1. MyIsam
MyIsam 存儲引擎獨立於操作系統,也就是可以在windows上使用,也可以比較簡單的將數據轉移到linux操作系統上去。這種存儲引擎在創建表的時候,會創建三個文件,一個是.frm文件用於存儲表的定義,一個是.MYD文件用於存儲表的數據,另一個是.MYI文件,存儲的是索引。操作系統對大文件的操作是比較慢的,這樣將表分爲三個文件,那麼.MYD這個文件單獨來存放數據自然可以優化數據庫的查詢等操作。
1. 不支持事務,但是並不代表着有事務操作的項目不能用MyIsam存儲引擎,可以在service層進行根據自己的業務需求進行相應的控制。
2. 不支持外鍵。
3. 查詢速度很快,如果數據庫insert和update的操作比較多的話比較適用。
4. 對錶進行加鎖。
2. Mrg_Myisam
Merge存儲引擎,是一組MyIsam的組合,也就是說,他將MyIsam引擎的多個表聚合起來,但是他的內部沒有數據,真正的數據依然是MyIsam引擎的表中,但是可以直接進行查詢、刪除更新等操作。
比如:我們可能會遇到這樣的問題,同一種類的數據會根據數據的時間分爲多個表,如果這時候進行查詢的話,就會比較麻煩,Merge可以直接將多個表聚合成一個表統一查詢,然後再刪除Merge表(刪除的是定義),原來的數據不會影響。
3. Memory
Memory採用的邏輯介質是內存,響應速度應該是很快的,但是當mysqld守護進程崩潰的時候數據會丟失,另外,要求存儲的數據是數據長度不變的格式,比如,Blob和Text類型的數據不可用(長度不固定的)。
使用Memory存儲引擎情況:
1. 目標數據比較小,而且非常頻繁的進行訪問,在內存中存放數據,如果太大的數據會造成內存溢出。可以通過參數max_heap_table_size控制Memory表的大小,限制Memory表的最大的大小。
2. 如果數據是臨時的,而且必須立即可用得到,那麼就可以放在內存中。
3. 存儲在Memory表中的數據如果突然間丟失的話也沒有太大的關係。
【注】 Memory同時支持散列索引和B樹索引,B樹索引可以使用部分查詢和通配查詢,也可以使用<,>和>=等操作符方便數據挖掘,散列索引相等的比較快但是對於範圍的比較慢很多。
4. Blackhole
“黑洞”存儲引擎,他會丟棄所有的插入的數據,服務器會記錄下Blackhole表的日誌,所以可以用於複製數據到備份數據庫。看其他的一些資料說:可以用來充當dummy master,利用blackHole充當一個“dummy master”來減輕master的負載,對於master來說“dummy master” 還是一個slave的角色,還有充當日誌服務器等等。
5. CSV
可以將scv文件作爲MySql的表來使用,但是不支持索引。CSV引擎表所有的字段都必須爲非空的,創建的表有兩個一個是CSV文件和CSM文件。
6. Performance_Schema
MySQL5.5以後新增了一個存儲引擎,就是Performance_Schema,他主要是用來收集數據庫服務器的性能參數。MySQL用戶不能創建存儲該類型的表。
他提供了以下的功能:
1. 提供進程等待的詳細信息,包括鎖、互斥變量、文件信息。
2. 保存歷史的事件彙總信息,爲Mysql服務器的性能做出詳細的判斷。
3. 對於新增和刪除監控時間點都非常容易,並可以隨意的改變Mysql服務器的監控週期
需要在配置文件my.cnf中進行配置才能開啓。
7. Archive
archive是歸檔的意思,僅僅支持插入和查詢兩種功能,在MySQL5.5以後支持索引功能,他擁有很好的壓縮機制,使用zlib壓縮庫,在記錄請求的時候實時的進行壓縮,經常被用來作爲倉庫使用。適合存儲大量的獨立的作爲歷史記錄的數據。擁有很高的插入速度但是對查詢的支持較差。
8. Federated
Federated存儲引擎是訪問MySQL服務器的一個代理,儘管該引擎看起來提供了一個很好的跨服務器的靈活性,但是經常帶來問題,默認是禁用的。
9. InnoDB
InnoDB是一個事務型的存儲引擎,有行級鎖定和外鍵約束,適用於以下的場合:
1. 更新多的表,適合處理多重併發的更新請求。
2. 支持事務。
3. 可以從災難中恢復(通過bin-log日誌等)。
4. 外鍵約束。只有他支持外鍵。
5. 支持自動增加列屬性auto_increment。
MyISam和InnoDB實例比較
這裏我選擇兩個比較重點的存儲引擎實驗下速度之類的性能,對比一下看看。
1. 創建兩張表分別以MyIsam和InnoDB作爲存儲引擎。
-
create table testMyIsam(
-
-> id int unsigned primary key auto_increment,
-
-> name varchar(20) not null
-
-> )engine=myisam;
-
create table testInnoDB( id int unsigned primary key auto_increment, name varchar(20) not null )engine=innodb;
兩張表內容是一致的但是存儲引擎不一樣,下面我們從插入數據開始進行測試比較。
這裏當然不能手動的插入,創建一個存儲過程插入一百萬的數據。
-
mysql> create procedure insertMyIsam()
-
-> begin
-
-> set @i = 1;
-
-> while @i <= 1000000
-
-> do
-
-> insert into testMyIsam(name) values(concat("wy", @i));
-
-> set @i = @i + 1;
-
-> end while;
-
-> end//
-
mysql> create procedure insertInnoDB()
-
-> begin
-
-> set @i = 1;
-
-> while @i <= 1000000
-
-> do
-
-> insert into testInnoDB(name) values(concat("wy", @i));
-
-> set @i = @i + 1;
-
-> end while;
-
-> end//
插入(一百萬條)MyIsam存儲引擎的表中的時間如下:
-
mysql> call insertMyIsam;
-
-> //
-
Query OK, 0 rows affected (49.69 sec)
插入(一百萬條)InnoDB存儲引擎的表中的時間如下:
-
mysql> create procedure insertInnoDB()
-
-> begin
-
-> set @i = 1;
-
-> while @i <= 1000000
-
-> do
-
-> insert into testInnoDB(name) values(concat("wy", @i));
-
-> set @i = @i + 1;
-
-> end while;
-
-> end//
-
Query OK, 0 rows affected (0.00 sec)
-
-
mysql> call insertInnoDB;
-
-> //
-
Query OK, 0 rows affected (1 hour 38 min 14.12 sec)
我的心情是複雜的,這裏當時默認的是開啓了自動提交事務了,所以執行速度很慢,可以先將自動提交關閉,然後再調用存儲過程插入一百萬的數據,執行完成之後再開啓自動提交,這樣會快很多。
-
mysql> set autocommit = 0;
-
Query OK, 0 rows affected (0.00 sec)
-
-
mysql> call insertInnoDB;
-
Query OK, 0 rows affected (36.52 sec)
-
-
mysql> set autocommit = 1;
-
Query OK, 0 rows affected (5.72 sec)
3. 查詢數據總數目
下面是InnoDB的SQL語句的分析:
-
mysql> desc select count(*) from testInnoDB\G;
-
*************************** 1. row ***************************
-
id: 1
-
select_type: SIMPLE
-
table: testInnoDB
-
type: index
-
possible_keys: NULL
-
key: PRIMARY
-
key_len: 4
-
ref: NULL
-
rows: 997134
-
Extra: Using index
-
1 row in set (0.03 sec)
下面是MyIsam(他的數據總數存儲在其他的表中所以這裏是沒有影響行數的)的SQL語句的分析:
-
mysql> desc select count(*) from testMyIsam\G;
-
*************************** 1. row ***************************
-
id: 1
-
select_type: SIMPLE
-
table: NULL
-
type: NULL
-
possible_keys: NULL
-
key: NULL
-
key_len: NULL
-
ref: NULL
-
rows: NULL
-
Extra: Select tables optimized away
-
1 row in set (0.00 sec)
4. 查詢某一範圍的數據
4.1 沒有索引的列
-
mysql> select * from testMyIsam where name > "wy100" and name < "wy100000";+
-
| id | name |
-
+
-
| 1000 | wy1000 |
-
| 10000 | wy10000 |
-
+
-
2 rows in set (0.43 sec)
-
-
mysql> select * from testInnoDB where name > "wy100" and name < "wy100000";+
-
| id | name |
-
+
-
| 1000 | wy1000 |
-
| 10000 | wy10000 |
-
+
4.2 有索引的列
對於使用MyIsam存儲引擎的表:
-
<pre name="code" class="sql">select * from testMyIsam where id > 10 and id < 999999;
執行時間:
-
<pre name="code" class="sql">999988 rows in set (0.91 sec)
對於使用了InnoDB存儲引擎的表:
-
select * from testInnoDB where id > 10 and id < 999999;
-
999988 rows in set (0.69 sec)
但是好像我沒看出來多大的差距,可能是數據太少的原因吧。
-
mysql> select * from testInnoDB where name = "wy999999";
-
+
-
| id | name |
-
+
-
| 999999 | wy999999 |
-
+
-
1 row in set (0.20 sec)
-
-
mysql> select * from testMyIsam where name = "wy999999";
-
+
-
| id | name |
-
+
-
| 999999 | wy999999 |
-
+
-
1 row in set (0.16 sec)