首先我們知道MyISM和InnoDB索引都是由B+樹實現的,但在索引管理數據方式上卻有所不同。
InnoDB是聚集索引,數據文件是和(主鍵)索引綁在一起的,即索引 + 數據 = 整個表數據文件,通過主鍵索引到整個記錄,必須要有主鍵,通過主鍵索引效率很高。但是輔助索引需要兩次查詢,因為輔助索引是以建索引的字段為關鍵字索引到主鍵,所以需要兩次,先查詢到主鍵,然后再通過主鍵查詢到數據。因此,主鍵不應該過大,因為主鍵太大,其他索引也都會很大。話不多說上圖:
主鍵索引:以主鍵索引到整條記錄
輔助索引:以另一字段索引到主鍵
MyISAM是非聚集索引,也是使用B+Tree作為索引結構,索引和數據文件是分離的,索引保存的是數據文件的指針。主鍵索引和輔助索引是獨立的。也就是說:InnoDB的B+樹主鍵索引的葉子節點就是數據文件,輔助索引的葉子節點是主鍵的值;而MyISAM的B+樹主鍵索引和輔助索引的葉子節點都是數據文件的地址指針。
主鍵索引:以關鍵字索引到記錄的地址
輔助索引:以某字段索引到記錄地址
從索引實現方面我們也可以看出來InnoDB表數據文件本身就是索引文件,他們是一個整體,而對於MyISAM來說數據文件和索引文件則是分開的。
鎖方面:
mysql支持三種鎖定級別,行級、頁級、表級;
MyISAM支持表級鎖定,提供與 Oracle 類型一致的不加鎖讀取(non-locking read in SELECTs)
InnoDB支持行級鎖,但值得注意的是InnoDB的行鎖是加到索引上的,所以在某次查找時沒有用上索引,InnoDB表同樣會鎖全表。
事務方面:
InnoDB具有事務,支持4個事務隔離級別,回滾,崩潰修復能力和多版本並發的事務安全,包括ACID。如果應用中需要執行大量的INSERT或UPDATE操作,則應該使用InnoDB,以事務為單位操作可以提高多用戶並發操作的性能。
MyISAM管理非事務表。它提供高速存儲和檢索,以及全文搜索能力。如果應用中需要執行大量的SELECT查詢,那么MyISAM是更好的選擇
並發
MyISAM讀寫互相阻塞:不僅會在寫入的時候阻塞讀取,MyISAM還會在讀取的時候阻塞寫入,但讀本身並不會阻塞另外的讀。
InnoDB 讀寫阻塞與事務隔離級別相關。
其他
InnoDB不保存表的具體行數,執行select count(*) from table時需要全表掃描。而MyISAM用一個變量保存了整個表的行數,執行上述語句時只需要讀出該變量即可,速度很快;
不使用到索引的情況:
用or分隔開的條件,如果or前的條件中的列有索引,而后面的列沒有索引,那么涉及到的索引都不會被用到,例如:select * from table_name where key1='a' or key2='b';如果在key1上有索引而在key2上沒有索引,則該查詢也不會走索引
復合索引,如果索引列不是復合索引的第一部分,則不使用索引(即不符合最左前綴),例如,復合索引為(key1,key2),則查詢select * from table_name where key2='b';將不會使用索引
如果like是以‘%’開始的,則該列上的索引不會被使用。例如select * from table_name where key1 like '%a';該查詢即使key1上存在索引,也不會被使用
如果列為字符串,則where條件中必須將字符常量值加引號,否則即使該列上存在索引,也不會被使用。例如,select * from table_name where key1=1;如果key1列保存的是字符串,即使key1上有索引,也不會被使用。
where語句中使用 <>和 !=。