Mysql優化(二):索引及其原理分析、數據引擎

1. 索引

1.1 什麼是索引

索引用來快速地尋找那些具有特定值的記錄,所有MySQL索引都以B-樹的形式保存。如果沒有索引,執行查詢時MySQL必須從第一個記錄開始掃描整個表的所有記錄,直至找到符合要求的記錄。表裏面的記錄數量越多,這個操作的代價就越高。如果作爲搜索條件的列上已經創建了索引,MySQL無需掃描任何記錄即可迅速得到目標記錄所在的位置。如果表有1000個記錄,通過索引查找記錄至少要比順序掃描記錄快100倍。

1.2 索引的分類

1.2.1 普通索引

普通索引(由關鍵字KEY或INDEX定義的索引)最基本的索引,它沒有任何限制,它的唯一任務是加快對數據的訪問速度。因此,應該只爲那些最經常出現在查詢條件(WHEREcolumn=)或排序條件(ORDERBYcolumn)中的數據列創建索引。只要有可能,就應該選擇一個數據最整齊、最緊湊的數據列(如一個整數類型的數據列)來創建索引。

  1. 建表的時候一起創建
CREATE TABLE mytable (
	name VARCHAR(32) ,
	INDEX index_mytable_name (name)
);
  1. 建表後,直接創建索引
CREATE INDEX index_mytable_name ON mytable(name);
  1. 修改表結構
ALTER TABLE mytable ADD INDEX index_mytable_name (name);

1.2.2 唯一索引

這種索引和前面的“普通索引”基本相同,但有一個區別:索引列的所有值都只能出現一次,即必須唯一。如果是組合索引,則列值的組合必須唯一。唯一性索引可以用以下幾種方式創建:

建表的時候一起創建

CREATE TABLE mytable (
`name` VARCHAR(32) ,
UNIQUE index_unique_mytable_name (`name`)
);

建表後,直接創建索引

CREATE UNIQUE INDEX index_mytable_name ON mytable(name);

修改表結構

ALTER TABLE mytable ADD UNIQUE INDEX index_mytable_name (name);

注:如果是字符串字段,還可以指定索引的長度,在列命令後面加上索引長度就可以了(例如:name(11))
unique字段可以爲NULL,並可以有多NULL, 但是如果是具體內容,則不能重複,
但是不能存有重複的空字符串’’

1.2.3 主鍵索引

主鍵是一種唯一性索引,但它必須指定爲“PRIMARY KEY”。如果你曾經用過AUTO_INCREMENT類型的列,你可能已經熟悉主鍵之類的概念了。主鍵一般在創建表的時候指定,例如“CREATE TABLE tablename ( […], PRIMARY KEY (列的列表) ); ”。但是,我們也可以通過修改表的方式加入主鍵,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每個表只能有一個主鍵。

當一張表,把某個列設爲主鍵的時候,則該列就是主鍵索引

create table aaa
(id int unsigned primary key auto_increment ,
name varchar(32) not null default '');

這是id 列就是主鍵索引.

create table bbb (id int , name varchar(32) not null default '');

如果你創建表時,沒有指定主鍵索引,也可以在創建表後,在添加, 指令:
實例:

alter table 表名 add primary key (列名);

刪除主鍵索引

alter table articles drop primary key;

1.2.4 組合索引

指多個字段上創建的索引,只有在查詢條件中使用了創建索引時的第一個字段,索引纔會被使用。使用組合索引時遵循最左前綴集合。
創建方法:

  1. 建表的時候一起創建
CREATE TABLE mytable (
`id` int(11) ,
`name` VARCHAR(32) ,
INDEX index_mytable_id_name (`id`,`name`)
);
  1. 建表後,直接創建索引
CREATE INDEX index_mytable_id_name ON mytable(id,name);
  1. 修改表結構
ALTER TABLE mytable ADD INDEX index_mytable_id_name (id,name);

1.2.5 全文索引

主要用來查找文本中的關鍵字,而不是直接與索引中的值相比較。

CREATE TABLE articles (
       id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
       title VARCHAR(200),
       body TEXT,
       FULLTEXT (title,body)
     )engine=myisam charset utf8;

INSERT INTO articles (title,body) VALUES
     ('MySQL Tutorial','DBMS stands for DataBase ...'),
     ('How To Use MySQL Well','After you went through a ...'),
     ('Optimizing MySQL','In this tutorial we will show ...'),
     ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
     ('MySQL vs. YourSQL','In the following database comparison ...'),
     ('MySQL Security','When configured properly, MySQL ...');

錯誤用法:索引失效

select * from articles where body like '%mysql%';

正確用法:

select * from articles where match(title,body) against ( 'database')

說明:
在mysql中fulltext 索引只針對 myisam生效
mysql自己提供的fulltext針對英文生效->sphinx (coreseek) 技術處理中文
使用方法是 match(字段名…) against(‘關鍵字’)

全文索引:停止詞, 因爲在一個文本中,創建索引是一個無窮大的數,因此,對一些常用詞和字符,就不會創建,這些詞,稱爲停止詞.比如(a,b,mysql,the)

mysql> select match(title,body) against ('database') from articles;
(輸出的是每行和database的匹配度)

最後要說明的是mysql的全文索引一般在實際開發中很少用到,並且主流的數據引擎innoDB並不支持全文索引,比較流行的搜索引擎ElasticSearch與Solor可以替代全文索引進行搜索。

根據功能劃分三種索引

根據數據庫的功能,可以在數據庫設計器中創建三種索引:唯一索引、主鍵索引和聚集索引。

唯一索引
唯一索引是不允許其中任何兩行具有相同索引值的索引。
當現有數據中存在重複的鍵值時,大多數數據庫不允許將新創建的唯一索引與表一起保存。數據庫還可能防止添加將在表中創建重複鍵值的新數據。例如,如果在 employee 表中職員的姓(lname)上創建了唯一索引,則任何兩個員工都不能同姓。

主鍵索引
數據庫表經常有一列或列組合,其值唯一標識表中的每一行。該列稱爲表的主鍵。在數據庫關係圖中爲表定義主鍵將自動創建主鍵索引,主鍵索引是唯一索引的特定類型。該索引要求主鍵中的每個值都唯一。當在查詢中使用主鍵索引時,它還允許對數據的快速訪問。

聚集索引
在聚集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同。一個表只能包含一個聚集索引。
如果某索引不是聚集索引,則表中行的物理順序與鍵值的邏輯順序不匹配。與非聚集索引相比,聚集索引通常提供更快的數據訪問速度。

查詢表中的索引

desc  表名;   顯示錶的狀態,但不能顯示索引名稱
show index from 表名
show keys from 表名

1.3 索引的實現原理

數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現通常使用 B 樹(B-TREE,千萬不要讀成B減樹)及其變種 B+ 樹(B-TREE)。
在數據之外,數據庫系統還維護着滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。
爲表設置索引要付出代價的:一是增加了數據庫的存儲空間,二是在插入和修改數據時要花費較多的時間(因爲索引也要隨之變動)。
在這裏插入圖片描述在這裏插入圖片描述
上圖展示了一種可能的索引方式。左邊是數據表,一共有兩列七條記錄,最左邊的是數據記錄的物理地址(注意邏輯上相鄰的記錄在磁盤上也並不是一定物理相鄰的)。爲了加快 Col2 的查找,可以維護一個右邊所示的二叉查找樹,每個節點分別包含索引鍵值和一個指向對應數據記錄物理地址的指針,這樣就可以運用二叉查找在 O(log2n)的複雜度內獲取到相應數據。

局部性原理與磁盤預讀

由於存儲介質的特性,磁盤本身存取就比主存慢很多,再加上機械運動耗費,磁盤的存取速度往往是主存的幾百分分之一,因此爲了提高效率,要儘量減少磁盤 I/O。爲了達到這個目的,磁盤往往不是嚴格按需讀取,而是每次都會預讀,即使只需要一個字節,磁盤也會從這個位置開始,順序向後讀取一定長度的數據放入內存。這樣做的理論依據是計算機科學中著名的局部性原理:當一個數據被用到時,其附近的數據也通常會馬上被使用。程序運行期間所需要的數據通常比較集中。

由於磁盤順序讀取的效率很高(不需要尋道時間,只需很少的旋轉時間),因此對於具有局部性的程序來說,預讀可以提高 I/O 效率。
預讀的長度一般爲頁(page)的整倍數。頁是計算機管理存儲器的邏輯塊,硬件及操作系統往往將主存和磁盤存儲區分割爲連續的大小相等的塊,每個存儲塊稱爲一頁(在許多操作系統中,頁得大小通常爲 4k),主存和磁盤以頁爲單位交換數據。當程序要讀取的數據不在主存中時,會觸發一個缺頁異常,此時系統會向磁盤發出讀盤信號,磁盤會找到數據的起始位置並向後連續讀取一頁或幾頁載入內存中,然後異常返回,程序繼續運行。

B-/+Tree原理

B 樹

B 樹中每個節點包含了鍵值和鍵值對於的數據對象存放地址指針,所以成功搜索一個對象可以不用到達樹的葉節點。
成功搜索包括節點內搜索和沿某一路徑的搜索,成功搜索時間取決於關鍵碼所在的層次以及節點內關鍵碼的數量。
在 B 樹中查找給定關鍵字的方法是:首先把根結點取來,在根結點所包含的關鍵字 K1,…,kj 查找給定的關鍵字(可用順序查找或二分查找法),若找到等於給定值的關鍵字,則查找成功;否則,一定可以確定要查的關鍵字在某個 Ki 或 Ki+1 之間,於是取 Pi 所指的下一層索引節點塊繼續查找,直到找到,或指針 Pi 爲空時查找失敗。

B+ 樹

B+ 樹非葉節點中存放的關鍵碼並不指示數據對象的地址指針,非葉節點只是索引部分。所有的葉節點在同一層上,包含了全部關鍵碼和相應數據對象的存放地址指針,且葉節點按關鍵碼從小到大順序鏈接。如果實際數據對象按加入的順序存儲而不是按關鍵碼次數存儲的話,葉節點的索引必須是稠密索引,若實際數據存儲按關鍵碼次序存放的話,葉節點索引時稀疏索引。

B+ 樹有 2 個頭指針,一個是樹的根節點,一個是最小關鍵碼的葉節點。
所以 B+ 樹有兩種搜索方法:
一種是按葉節點自己拉起的鏈表順序搜索。
一種是從根節點開始搜索,和 B 樹類似,不過如果非葉節點的關鍵碼等於給定值,搜索並不停止,而是繼續沿右指針,一直查到葉節點上的關鍵碼。所以無論搜索是否成功,都將走完樹的所有層。
B+ 樹中,數據對象的插入和刪除僅在葉節點上進行。
這兩種處理索引的數據結構的不同之處:
a,B 樹中同一鍵值不會出現多次,並且它有可能出現在葉結點,也有可能出現在非葉結點中。而 B+ 樹的鍵一定會出現在葉結點中,並且有可能在非葉結點中也有可能重複出現,以維持 B+ 樹的平衡。
b,因爲 B 樹鍵位置不定,且在整個樹結構中只出現一次,雖然可以節省存儲空間,但使得在插入、刪除操作複雜度明顯增加。B+ 樹相比來說是一種較好的折中。
c,B 樹的查詢效率與鍵在樹中的位置有關,最大時間複雜度與 B+ 樹相同(在葉結點的時候),最小時間複雜度爲 1(在根結點的時候)。而 B+ 樹的時候複雜度對某建成的樹是固定的。可以掃描2的次方。

B-/+Tree 索引的性能分析

上文說過一般使用磁盤 I/O 次數評價索引結構的優劣。先從 B-Tree 分析,根據 B-Tree 的定義,可知檢索一次最多需要訪問 h(樹的高度) 個節點。數據庫系統的設計者巧妙利用了磁盤預讀原理,將一個節點的大小設爲等於一個頁,這樣每個節點只需要一次 I/O 就可以完全載入。爲了達到這個目的,在實際實現 B-Tree 還需要使用如下技巧:
每次新建節點時,直接申請一個頁的空間,這樣就保證一個節點物理上也存儲在一個頁裏,加之計算機存儲分配都是按頁對齊的,就實現了一個 node 只需一次 I/O。

B-Tree 中一次檢索最多需要 h-1 次 I/O(根節點常駐內存),漸進複雜度爲 O(h)=O(logdN)。一般實際應用中,出度 d 是非常大的數字,通常超過 100,因此 h 非常小(通常不超過 3)。

而紅黑樹這種結構,h 明顯要深的多。由於邏輯上很近的節點(父子)物理上可能很遠,無法利用局部性,所以紅黑樹的 I/O 漸進複雜度也爲 O(h),效率明顯比 B-Tree 差很多。
綜上所述,用 B-Tree 作爲索引結構效率是非常高的。

1.4 MySQL explain執行計劃解讀

引言:
實際項目開發中,由於我們不知道實際查詢的時候數據庫裏發生了什麼事情,數據庫軟件是怎樣掃描表、怎樣使用索引的,因此,我們能感知到的就只有
sql語句運行的時間,在數據規模不大時,查詢是瞬間的,因此,在寫sql語句的時候就很少考慮到性能的問題。但是當數據規模增大,如千萬、億的時候,我們運
行同樣的sql語句時卻發現遲遲沒有結果,這個時候才知道數據規模已經限制了我們查詢的速度。所以,查詢優化和索引也就顯得很重要了。

問題:
當我們在查詢前能否預先估計查詢究竟要涉及多少行、使用哪些索引、運行時間呢?答案是能的,mysql提供了相應的功能和語法來實現該功能。

分析:
MySql提供了EXPLAIN語法用來進行查詢分析,在SQL語句前加一個"EXPLAIN"即可。比如我們要分析如下SQL語句:

explain select * from table where table.id = 1 

運行上面的sql語句後你會看到,下面的表頭信息:

table | type | possible_keys | key | key_len | ref | rows | Extra

EXPLAIN列的解釋

  • table 顯示這一行的數據是關於哪張表的
  • type
    這是重要的列,顯示連接使用了何種類型。從最好到最差的連接類型爲const、eq_reg、ref、range、indexhe和ALL
    說明:不同連接類型的解釋(按照效率高低的順序排序)
    system:表只有一行:system表。這是const連接類型的特殊情況。
    const :表中的一個記錄的最大值能夠匹配這個查詢(索引可以是主鍵或惟一索引)。因爲只有一行,這個值實際就是常數,因爲MYSQL先讀這個值然後把它當做常數來對待。
    eq_ref:在連接中,MYSQL在查詢時,從前面的表中,對每一個記錄的聯合都從表中讀取一個記錄,它在查詢使用了索引爲主鍵或惟一鍵的全部時使用。
    ref:這個連接類型只有在查詢使用了不是惟一或主鍵的鍵或者是這些類型的部分(比如,利用最左邊前綴)時發生。對於之前的表的每一個行聯合,全部記錄都將從表中讀出。這個類型嚴重依賴於根據索引匹配的記錄多少—越少越好。
    range:這個連接類型使用索引返回一個範圍中的行,比如使用>或<查找東西時發生的情況。
    index:這個連接類型對前面的表中的每一個記錄聯合進行完全掃描(比ALL更好,因爲索引一般小於表數據)。
    ALL:這個連接類型對於前面的每一個記錄聯合進行完全掃描,這一般比較糟糕,應該儘量避免。
  • possible_keys 顯示可能應用在這張表中的索引。如果爲空,沒有可能的索引。可以爲相關的域從WHERE語句中選擇一個合適的語句
  • key
    實際使用的索引。如果爲NULL,則沒有使用索引。很少的情況下,MYSQL會選擇優化不足的索引。這種情況下,可以在SELECT語句中使用
    USE INDEX(indexname)來強制使用一個索引或者用
    IGNORE INDEX(indexname)來強制MYSQL忽略索引
  • key_len 使用的索引的長度。在不損失精確性的情況下,長度越短越好
  • ref 顯示索引的哪一列被使用了,如果可能的話,是一個常數
  • rows MYSQL認爲必須檢查的用來返回請求數據的行數
  • Extra 關於MYSQL如何解析查詢的額外信息。
    例如:Using temporary和Using filesort,意思MYSQL根本不能使用索引,結果是檢索會很慢
    extra列返回結果的意義
    (1)Distinct :一旦mysql找到了與行相聯合匹配的行,就不再搜索了。
    (2)Not exists :mysql優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行,就不再搜索了。
    (3)Range checked for each Record(index map:#)
    :沒有找到理想的索引,因此對從前面表中來的每一個行組合,mysql檢查使用哪個索引,並用它來從表中返回行。這是使用索引的最慢的連接之一。
    (4)Using filesort:
    看到這個的時候,查詢就需要優化了。mysql需要進行額外的步驟來發現如何對返回的行排序。它根據連接類型以及存儲排序鍵值和匹配條件的全部行的行指針來排序全部行。
    (5)Using index :列數據是從僅僅使用了索引中的信息而沒有讀取實際的行動的表返回的,這發生在對錶的全部的請求列都是同一個索引的部分的時候。
    (6)Using temporary :看到這個的時候,查詢需要優化了。這裏,mysql需要創建一個臨時表來存儲結果,這通常發生在對不同的列集進行ORDER BY上,而不是GROUP BY上。
    (7)Where used :使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給用戶。如果不想返回表中的全部行,並且連接類型ALL或index,這就會發生,或者是查詢有問題。

因此,弄明白了explain語法返回的每一項結果,我們就能知道查詢大致的運行時間了,如果查詢裏沒有用到索引、或者需要掃描的行過多,那麼可以感到明顯的延遲。因此需要改變查詢方式或者新建索引。mysql中的explain語法可以幫助我們改寫查詢,優化表的結構和索引的設置,從而最大地提高查詢效率。當然,在大規模數據量時,索引的建立和維護的代價也是很高的,往往需要較長的時間和較大的空間,如果在不同的列組合上建立索引,空間的開銷會更大。因此索引最好設置在需要經常查詢的字段中。

1.5 使用索引的優缺點

創建索引可以大大提高系統的性能。
第一,通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。
第二,可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。
第三,可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
第四,在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。
第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

也許會有人要問:增加索引有如此多的優點,爲什麼不對錶中的每一個列創建一個索引呢?因爲,增加索引也有許多不利的方面。

第一,創建索引和維護索引要耗費時間,這種時間隨着數據量的增加而增加。
第二,索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。
第三,當對錶中的數據進行DML(update、delete、insert)的時候,索引也要動態的維護,即重新整理,這樣就降低了數據的維護速度。

1.6 索引的適用範圍

索引是建立在數據庫表中的某些列的上面。在創建索引的時候,應該考慮在哪些列上可以創建索引,在哪些列上不能創建索引。
一般來說,應該在這些列上創建索引:

  1. 在經常需要搜索的列上,可以加快搜索的速度;
  2. 在作爲主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;
  3. 在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;
  4. 在經常需要根據範圍進行搜索的列上創建索引,因爲索引已經排序,其指定的範圍是連續的;
  5. 在經常需要排序的列上創建索引,因爲索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;
  6. 在經常使用在 WHERE 子句中的列上面創建索引,加快條件的判斷速度。

同樣,對於有些列不應該創建索引。
一般來說,不應該創建索引的的這些列具有下列特點:

  1. 對於那些在查詢中很少使用或者參考的列不應該創建索引。這是因爲,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。
  2. 對於那些只有很少數據值的列也不應該增加索引。這是因爲,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。
  3. 對於那些定義爲 text, image 和 bit 數據類型的列不應該增加索引。這是因爲,這些列的數據量要麼相當大,要麼取值很少。
  4. 當修改性能遠遠大於檢索性能時,不應該創建索引。這是因爲,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。

1.7 查詢索引使用率

show status like ‘handler_read%;

大家可以注意:
handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數。
handler_read_rnd_next:這個值越高,說明查詢低效。

2. SQL優化技巧&索引注意事項

  1. 使用group by 分組查詢是,默認分組後,還會排序,可能會降低速度,
    在group by 後面增加 order by null 就可以防止排序.
explain select * from emp  group by deptno order by null;
  1. 有些情況下,可以使用連接來替代子查詢。因爲使用join,MySQL不需要在內存中創建臨時表。
select * from dept, emp where dept.deptno=emp.deptno; [簡單處理方式]
select * from dept left join emp on dept.deptno=emp.deptno; 
[左外連接,更ok!]
  1. 對查詢進行優化,要儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引
  2. 應儘量避免在 where 子句中對字段進行 null 值判斷,否則可能會導致引擎放棄使用索引(注意是可能,判空是否會導致索引失效並不一定,肯能和版本或其它因素有關,推薦閱讀Mysql數據庫索引IS NUll ,IS NOT NUll ,!= 是否走索引)而進行全表掃描,如:
select id from t where num is null

總而言之最好不要給數據庫留 NULL,儘可能的使用 NOT NULL 填充數據庫.

還需注意的是,不要以爲 NULL 不需要空間,
比如:char(100) 型,在字段建立時,空間就固定了, 不管是否插入值(NULL 也包含在內),都是佔用 100 個字符的空間的,如果是 varchar 這樣的變長字段, null 不佔用空間。
可以在 num 上設置默認值 0,確保表中 num 列沒有 null 值,然後這樣查詢:

select id from t where num = 0
  1. 如果索引量非常大使用緩存
  2. 對於創建的多列索引,如果不是使用第一部分,則不會創建索引。
    如下創建一個多列索引:
alter table dept add index my_ind (dname,loc); //  dname 左邊的列,loc就是右邊的列

使用如下語句進行查詢:

explain select * from dept where loc='aaa'

就不會使用到索引

  1. 模糊查詢在like前面有百分號開頭會失效。
    如:
select * from dept where name  like '%洺%'

而下面的語句將會仍然有效

select * from dept where name  like '洺%'
  1. 如果條件中有or,即使其中有條件帶索引也不會使用。換言之,就是要求使用的所有字段,都必須建立索引, 我們建議大家儘量避免使用or 關鍵字
  2. 如果列類型是字符串,那一定要在條件中將數據使用引號引用起來。否則不使用索引。(添加時,字符串必須’’), 也就是,如果列是字符串類型,就一定要用 ‘’ 把他包括起來.
  3. 如果mysql估計使用全表掃描要比使用索引快,則不使用索引。

3. MySQL數據引擎myisam&INNODB

  • myisam 存儲: 如果表對事務要求不高,同時是以查詢和添加爲主的,我們考慮使用
  • INNODB 存儲: 對事務要求高,保存的數據都是重要數據,我們建議使用INNODB,比如訂單表,賬號表.

3.1 不同儲存引擎的索引類型

存儲引擎 允許的索引類型
myisam btree
innodb btree
memory/yeap Hash,btree

3.2 MyISAM 和 INNODB的區別

  1. 事務安全(MyISAM不支持事務,INNODB支持事務)
  2. 查詢和添加速度(MyISAM批量插入速度快)
  3. 支持全文索引(MyISAM支持全文索引,INNODB不支持全文索引)
  4. 鎖機制(MyISAM時表鎖,innodb是行鎖)
  5. 外鍵 MyISAM 不支持外鍵, INNODB支持外鍵. (在PHP開發中,通常不設置外鍵,通常是在程序中保證數據的一致)
    Memory 存儲,比如我們數據變化頻繁,不需要入庫,同時又頻繁的查詢和修改,我們考慮使用memory, 速度極快. (如果mysql重啓的話,數據就不存在了)

3.3 Myisam注意事項

如果你的數據庫的存儲引擎是myisam,請一定記住要定時進行碎片整理
舉例說明:

create table test100(id int unsigned ,name varchar(32))engine=myisam;
insert into test100 values(1,’aaaaa’);
insert into test100 values(2,’bbbb’);
insert into test100 values(3,’ccccc’);
insert into test100 select id,name from test100;

這樣進行插入每執行一次語句數據文件就會增大一倍,可以在mysql的data文件夾下觀察數據文件大小的變化,然後使用刪除語句進行刪除,會發現數據文件實際上並未被刪除。

所以我們一定要進行碎片化整理

optimize table test100;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章