MySQL中InnoDB與MyISAM區別

show tablestatus;
 
  查看錶採用何種引擎。

 
   MySQLAdministrator建數據庫的時候,表缺省是InnoDB類型。原來是MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持。
 
   MyISAM類型的表強調的是性能,其執行數度比InnoDB類型更快,但是不提供事務支持,而InnoDB提供事務支持以及外部鍵等高級數據庫功能。這樣就可以根據數據表不同的用處是用不同的存儲類型。

 
  另外,MyISAM類型的二進制數據文件可以在不同操作系統中遷移。也就是可以直接從Windows系統拷貝到linux系統中使用。
--------------------------------------------------------------
 
  mysql數據庫中最常使用的兩種表類型爲 innodb和myisam。這兩種類型各有優缺點,視具體應用而定。
 
   InnoDB 給MySQL 提供了具有事務(commit)、回滾(rollback)和崩潰修復能力(crash recoverycapabilities)的事務安全(transaction-safe (ACID compliant))型表。
 
   InnoDB提供了行鎖(locking on row level),提供與 Oracle 類型一致的不加鎖讀取(non-locking readinSELECTs)。這些特性均提高了多用戶併發操作的性能表現。  
 
  在InnoDB表中不需要擴大鎖定(lock escalation),因爲 InnoDB 的列鎖定(row levellocks)適宜非常小的空間。
 
   InnoDB 是MySQL 上第一個提供外鍵約束(FOREIGN KEY constraints)的表引擎。
 
   InnoDB的設計目標是處理大容量數據庫系統,它的 CPU 利用率是其它基於磁盤的關係數據庫引擎所不能比的。
 
   在技術上,InnoDB是一套放在 MySQL 後臺的完整數據庫系統,InnoDB 在主內存中建立其專用的緩衝池用於高速緩衝數據和索引。
 
   InnoDB 把數據和索引存放在表空間裏,可能包含多個文件,這與其它的不一樣,舉例來說,在 MyISAM中,表被存放在單獨的文件中。
 
   InnoDB 表的大小隻受限於操作系統的文件大小,一般爲 2 GB。
 
   InnoDB所有的表都保存在同一個數據文件 ibdata1 中(也可能是多個文件,或者是獨立的表空間文件),相對來說比較不好備份,免費的方案可以是拷貝數據文件、備份 binlog,或者用 mysqldump。

二、MyISAM

 
  MyISAM 是MySQL缺省存貯引擎 . 每張MyISAM表被存放在三個文件 。frm 文件存放表格定義。 數據文件是MYD (MYData) 。 索引文件是MYI (MYIndex)引伸。
 
  因爲MyISAM相對簡單所以在效率上要優於InnoDB..小型應用使用MyISAM是不錯的選擇.MyISAM表是保存成文件的形式,在跨平臺的數據轉移中使用MyISAM存儲會省去不少的麻煩。

MyIASM是IASM表的新版本,有如下擴展:
·二進制層次的可移植性。
·NULL列索引。
·對變長行比ISAM表有更少的碎片。
·支持大文件。
·更好的索引壓縮。
·更好的鍵嗎統計分佈。
·更好和更快的auto_increment處理。

以下是一些細節和具體實現的差別:

 
 1.InnoDB不支持FULLTEXT類型的索引。

 
  2.InnoDB中不保存表的具體行數,也就是說,執行select count(*) fromtable時,InnoDB要掃描一遍整個表來計算有多少行,但是MyISAM只要簡單的讀出保存好的行數即可。注意的是,當count(*)語句包含where條件時,兩種表的操作是一樣的。

 
 3.對於AUTO_INCREMENT類型的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中,可以和其他字段一起建立聯合索引。

 
  4.DELETE FROMtable時,InnoDB不會重新建立表,而是一行一行的刪除。

 
  5.LOAD TABLE FROMMASTER操作對InnoDB是不起作用的,解決方法是首先把InnoDB表改成MyISAM表,導入數據後再改成InnoDB表,但是對於使用的額外的InnoDB特性(例如外鍵)的表不適用。

 
 MyISAM類型的二進制數據文件可以在不同操作系統中遷移。
 
 另外,InnoDB表的行鎖也不是絕對的,假如在執行一個SQL語句時MySQL不能確定要掃描的範圍,InnoDB表同樣會鎖全表,例如updatetable set num=1 where name like “�a%” 再另外,使用兩種的選擇:
 
  如果你的數據執行大量的INSERT或UPDATE,出於性能方面的考慮,應該使用InnoDB表。
 
   如果執行大量的SELECT,MyISAM是更好的選擇。
 
  若需要使用事務處理,但是原來的數據表使用的是myisam,就需要改爲bdb或者innodb,這樣基於myisam的程序,將類型改爲innodb後,其程序不用改動……綜上所述,任何一種表都不是萬能的,只有恰當的針對業務類型來選擇合適的表類型,才能最大的發揮MySQL的性能優勢。

三、MyISAM和InnoDB優化

 
  1、key_buffer_size-這個參數,key_buffer_size表示索引緩衝區的大小,嚴格說是它決定了數據庫索引處理的速度,尤其是索引讀的速度。

 
  根據網絡一些高手寫的文章表示可以檢查狀態值Key_read_requests和Key_reads,即可知道key_buffer_size設置是否合理。比例key_reads /key_read_requests應該儘可能的低,至少是1:100,1:1000更好,雖然我還沒有找到理論的依據,但是,我在自己維護的幾臺實際運行良好的庫做過的測試後表明,這個比值接近1:20000,這從結果證明了他們說這話的正確性,我們不妨用之。

 
   這對MyISAM表來說非常重要。如果只是使用MyISAM表,可以把它設置爲可用內存的 30-40%。
 
   合理的值取決於索引大小、數據量以及負載 --
 
   記住,MyISAM表會使用操作系統的緩存來緩存數據,因此需要留出部分內存給它們,很多情況下數據比索引大多了。儘管如此,需要總是檢查是否所有的key_buffer 都被利用了 -- .MYI 文件只有 1GB,而 key_buffer 卻設置爲 4GB的情況是非常少的。這麼做太浪費了。
 
   如果你很少使用MyISAM表,那麼也保留低於 16-32MB 的 key_buffer_size以適應給予磁盤的臨時表索引所需。

2、innodb_buffer_pool_size - 這對Innodb表來說非常重要。
 
  Innodb相比MyISAM表對緩衝更爲敏感。
 
   MyISAM可以在默認的key_buffer_size 設置下運行的可以,
 
   然而Innodb在默認的innodb_buffer_pool_size 設置下卻跟蝸牛似的。
 
  0由於Innodb把數據和索引都緩存起來,無需留給操作系統太多的內存,因此如果只需要用Innodb的話則可以設置它高達 70-80%的可用內存。一些應用於 key_buffer 的規則有 -- 如果你的數據量不大,並且不會暴增,那麼無需把

3、innodb_additional_pool_size -這個選項對性能影響並不太多,至少在有差不多足夠內存可分配的操作系統上是這樣。不過如果你仍然想設置爲20MB(或者更大),因此就需要看一下Innodb其他需要分配的內存有多少。

 
  innodb_log_file_size在高寫入負載尤其是大數據集的情況下很重要。這個值越大則性能相對越高,但是要注意到可能會增加恢復時間。我經常設置爲64-512MB,跟據服務器大小而異。

4、innodb_log_buffer_size默認的設置在中等強度寫入負載以及較短事務的情況下,服務器性能還可以。如果存在更新操作峯值或者負載較大,就應該考慮加大它的值了。如果它的值設置太高了,可能會浪費內存 -- 它每秒都會刷新一次,因此無需設置超過1秒所需的內存空間。通常 8-16MB就足夠了。越小的系統它的值越小。

5、innodb_flush_logs_at_trx_commit
 

 
 是否爲Innodb比MyISAM慢1000倍而頭大?看來也許你忘了修改這個參數了。
 
  默認值是1,這意味着每次提交的更新事務(或者每個事務之外的語句)都會刷新到磁盤中,而這相當耗費資源,尤其是沒有電池備用緩存時。
 
   很多應用程序,尤其是從MyISAM轉變過來的那些,把它的值設置爲 2就可以了,也就是不把日誌刷新到磁盤上,而只刷新到操作系統的緩存上。日誌仍然會每秒刷新到磁盤中去,因此通常不會丟失每秒1-2次更新的消耗。
 
   如果設置 爲 0就快很多了,不過也相對不安全了 -- MySQL服務器崩潰時就會丟失一些事務。設置爲 2只會丟失刷新到操作系統緩存的那部分事務。

6、table_cache -- 打開一個表的開銷可能很大。
 
 例如MyISAM把MYI文件頭標誌該表正在使用中。你肯定不希望這種操作太頻繁,所以通常要加大緩存數量,使得足以最大限度地緩存打開的表。它需要用到操作系統的資源以及內存,對當前的硬件配置來說當然不是什麼問題了。
 
  如果你有200多個表的話,那麼設置爲 1024也許比較合適(每個線程都需要打開表),如果連接數比較大那麼就加大它的值。我曾經見過設置爲 100,000 的情況。

 
 table_cache指示表高速緩存的大小。當Mysql訪問一個表時,如果在Mysql表緩衝區中還有空間,那麼這個表就被打開並放入表緩衝區,這樣做的好處是可以更快速地訪問表中的內容。
 
 一般來說,可以通過查看數據庫運行峯值時間的狀態值Open_tables和Opened_tables,用以判斷是否需要增加table_cache的值,即如果open_tables接近table_cache的時候,並且Opened_tables這個值在逐步增加,那就要考慮增加這個值的大小了。

 
 在mysql默認安裝情況下,table_cache的值在2G內存以下的機器中的值默認時256到512,如果機器有4G內存,則默認這個值是2048,但這決不意味着機器內存越大,這個值應該越大,因爲table_cache加大後,使得mysql對SQL響應的速度更快了,不可避免的會產生更多的死鎖(dead lock),這樣反而使得數據庫整個一套操作慢了下來,嚴重影響性能。
 
 所以平時維護中還是要根據庫的實際情況去作出判斷,找到最適合你維護的庫的table_cache值,有人說:“性能優化是一門藝術”,這話一點沒錯。大凡藝術品,大都是經過千錘百煉,精雕細琢而成。

 
  這裏還要說明一個問題,就是table_cache加大後碰到文件描述符不夠用的問題,在mysql的配置文件中有這麼一段提示引用“Thenumber of open tables for all threads. Increasing this valueincreases the number of file descriptors that mysqldrequires.Therefore you have to make sure to set the amount of openfiles allowed to at least 4096 in the variable "open-files-limit"in” section [mysqld_safe]”

 
  說的就是要注意這個問題,一想到這裏,部分兄弟可能會用ulimit -n作出調整,但是這個調整實際是不對的,換個終端後,這個值又會回到原始值,所以最好用sysctl或者修改/etc/sysctl.conf文件,同時還要在配置文件中把open_files_limit這個參數增大,對於4G內存服務器,相信現在購買的服務器都差不多用4G的了,那這個這個open_files_limit至少要增大到4096,如果沒有什麼特殊情況,設置成8192就可以了。

7、thread_cache -- 線程的創建和銷燬的開銷可能很大,因爲每個線程的連接/斷開都需要。我通常至少設置爲16。如果應用程序中有大量的跳躍併發連接並且 Threads_Created的值也比較大,那麼我就會加大它的值。它的目的是在通常的操作中無需創建新線程

8、query_cache --如果你的應用程序有大量讀,而且沒有應用程序級別的緩存,那麼這很有用。不要把它設置太大了,因爲想要維護它也需要不少開銷,這會導致MySQL變慢。通常設置爲32-512Mb。設置完之後最好是跟蹤一段時間,查看是否運行良好。在一定的負載壓力下,如果緩存命中率太低了,就啓用它。

9、sort_buffer_size --如果你只有一些簡單的查詢,那麼就無需增加它的值了,儘管你有 64GB的內存。搞不好也許會降低性能。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章