MySQL學習筆記之五:存儲引擎和查詢緩存

一、存儲引擎

  1、InnoDB

    ⑴InnoDB是基於聚簇索引建立的,基於主鍵索引查詢時,性能較好;它的輔助索引中必須包含主鍵列;因此,若表上的索引較多,爲節約空間,主鍵應儘可能小

    ⑵InnoDB支持自適應hash索引、事務、行級鎖、熱備份,採用MVCC支持高併發;不支持全文索引

    ⑶表存儲格式

     ①將所有innodb表的數據放置同一個表空間中

         表結構定義:tb_name.frm (數據庫目錄下)

         數據和索引:統一的表空間文件中,默認路徑是數據目錄下ibdata#

       innodb_data_file_path:表空間文件的文件名稱及特性

         可使用相對(相對於innodb_data_home_dir而言)或絕對路徑,且可定義多個文件;

         例:innodb_data_file_path = ibdata1:20G;ibdata2:10G;ibdata3:1G:autoextend

       innodb_data_home_dir:表空間文件的存儲位置,省略時表示使用數據目錄(datadir變量定義的位置);

     ②每張表使用單獨表空間;MariaDB中已默認啓用此存儲格式    

         表結構定義:tb_name.frm

         數據和索引:tb_name.ibd

       SET {GLOBAL|SESSION} innodb_file_per_table = 'on';

       優點:遷移或備份數據更精細靈活

       缺點:DROP TABLE操作的性能較差

    ⑷InnoDB緩衝池:buffer pool,由InnoDB維護的內存空間,用於緩存索引及數據;緩衝池如果太大,預熱會比較慢。

       innodb_buffer_pool_size

    ⑸查看InnoDB存儲引擎的狀態:SHOW ENGINE INNODB STATUS;


  2、MyISAM

    ⑴MySQL 5.5.5之前的默認引擎

     支持全文索引、壓縮、空間函數;

     不支持外鍵約束

     不支持事務、行級鎖、熱備份

     讀寫互相阻塞

     崩潰後無法安全恢復

     支持延遲更新索引鍵(delay_key_write):每次修改表後,修改的索引數據不會立即寫入磁盤,而是寫入內存的鍵緩衝區,只有當清理鍵緩衝區或關閉表時纔會寫入磁盤,這樣提高了寫性能,但數據庫崩潰時,易造成索引損壞。

     MyISAM可以通過 key_buffer_size 緩存索引鍵,但此緩存只會緩存索引,不會緩存數據

     讀取數據快,佔用資源相對少

    ⑵表存儲格式:每張表都有三個文件(位於數據庫目錄下)

       tb_name.frm:表格式

       tb_name.MYD:數據

       tb_name.MYI:索引


  3、其它存儲引擎

     Memory:早期叫HEAP表,將數據放在內存中,因此訪問速度快,但無法持久存儲數據,顯式支持hash索引。

     CSV:將數據存儲爲文本文件,字段以逗號分隔;不支持索引,常用於數據交換的場景。

     Merge:MyISAM的變種,將多個MyISAM表合併表示爲一個虛擬表;

     Federated:訪問其它MySQL服務上數據的代理;MariaDB上用的是FederatedX

     Blackhole:沒有任何存儲機制,所以會丟棄所有的插入的數據;

     NDB:Cluster:mysql集羣的存儲引擎

     第三方存儲引擎:

       OLTP類:

         XtraDB:InnoDB的改進版

         PBXT:支持ACID和MVCC

         TokuDB:支持使用分形樹的索引結構,適用存儲大數據

       面向列的存儲的引擎:按列爲單位進行存儲,適合壓縮等,適用於存儲大數據

         Infobright, InfiniDB, LucidDB

       社區引擎:

         Aria:MyISAM的改進版,支持崩潰後安全恢復

         OQGraph:支持圖操作

         SphinxSE:爲sphinx全文搜索引擎提供了SQL接口;

         Spider:可以將數據切分成不同的分區,較透明實現分片功能;

  4、查看默認存儲引擎:

      show global variables like '%storage_engine';

      mysql 5.5之後默認存儲引擎爲innodb

  5、存儲引擎的選擇

      選擇標準:是否支持事務,熱備份,崩潰後恢復等

      數據倉庫建議使用MyISAM或Aria,在線事務處理建議使用InnoDB

MariaDB [testdb]> show engines;
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                                    | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                                         | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                                         | NO           | NO   | NO         |
| MRG_MyISAM         | YES     | Collection of identical MyISAM tables                                      | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears)             | NO           | NO   | NO         |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables                  | NO           | NO   | NO         |
| Aria               | YES     | Crash-safe tables with MyISAM heritage                                     | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                                     | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                                      | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Percona-XtraDB, Supports transactions, row-level locking, and foreign keys | YES          | YES  | YES        |
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.04 sec)

MariaDB [(none)]> show global variables like '%storage_engine';
+------------------------+--------+
| Variable_name          | Value  |
+------------------------+--------+
| default_storage_engine | InnoDB |
| storage_engine         | InnoDB |
+------------------------+--------+
2 rows in set (0.00 sec)

MariaDB [(none)]> select @@global.innodb_file_per_table;
+--------------------------------+
| @@global.innodb_file_per_table |
+--------------------------------+
|                              1 |
+--------------------------------+
1 row in set (0.00 sec)

MariaDB [(none)]> \! ls /mydata/data
aria_log.00000001  hellodb  ib_logfile0  multi-master.info  mysql-bin.000001  mysql-bin.000003	mysql-bin.000005  node1.err  performance_schema  testdb
aria_log_control   ibdata1  ib_logfile1  mysql		    mysql-bin.000002  mysql-bin.000004	mysql-bin.index   node1.pid  test
MariaDB [(none)]> \! ls /mydata/data/testdb
db.opt	students.frm  students.ibd  wuxia.frm  wuxia.ibd


二、查詢緩存  

  ⑴查詢的執行流程

    SELECT→[QUERY CACHE(查詢緩存)→]PARSER(解析器)→OPTIMIZER(優化器)→EXECUTING ENGINE(執行引擎)→STORAGE ENGINE

    開啓MySQL查詢緩存功能後,查詢緩存會保存查詢返回的完整結果,當查詢命中該緩存,MySQL會立刻返回結果,而跳過分析、優化和執行階段。

wKiom1blShXRro1VAAE5RrUrz-A756.png

  ⑵緩存的內容是key-value格式

      key:查詢語句的hash碼

      value:查詢語句的執行結果

  ⑶查詢緩存的優缺點

      優點:當查詢命中緩存時,就能直接返回結果,跳過了後續一系列繁瑣的過程,因此速度大大提升

      缺點:因爲要跟緩存中的鍵比對,因此,當查詢未命中緩存時,實際上是給整個查詢過程增加了一項開銷;此外,當併發量較大時,緩存成了資源爭用點,有可能成爲性能瓶頸。

  ⑷什麼樣的語句不會緩存?

      查詢語句中有不確定數據時不會緩存,比如current_time();

      一般來說,如果查詢中包含用戶自定義的函數、存儲函數、用戶變量、臨時表、mysql庫中表、或者任何包含權限信息表,都不會緩存;

  ⑸緩存什麼場景下會比較有效?

      對於需要牽扯大量資源的查詢非常適合啓用緩存;

      不適宜數據更新頻繁的場景,因爲那樣緩存失效很快

  ⑹與緩存功能相關的服務器變量:

        SHOW GLOBAL VARIABLES LIKE 'query_cache%';

      query_cache_limit: MySQL能夠緩存的最大查詢結果;如果某查詢的結果大於此值,則不會被緩存;

      query_cache_min_res_unit: 查詢緩存中分配內存的最小單位;

        計算公式:(query_cache_size-Qcache_free_memory)/Qcache_queries_in_cache,即(總空間-剩餘空間)/查詢的個數

      query_cache_size: 查詢緩存的總體可用空間;其必須爲1024的倍數,0表示關閉緩存

      query_cache_type: ON, OFF, DEMAND

        DEMAND:按需進行緩存,意思是隻有明確寫明要緩存的SELECT語句的結果纔會進行緩存; SQL_CACHE | SQL_NO_CACHE

      query_cache_wlock_invalidate:當其它會話鎖定此次查詢的資源時,是否不能再從緩存中返回數據;

  ⑺與緩存相關的狀態變量:

       SHOW GLOBAL STATUS LIKE 'Qcache%';

      Qcache_free_blocks

      Qcache_free_memory

      Qcache_hits: 緩存命中的次數

      Qcache_inserts: 插入的緩存的個數

      Qcache_lowmem_prunes: 由於可用緩存空間過低導致清理緩存的次數

      Qcache_not_cached

      Qcache_queries_in_cache: 仍留在緩存空間中的緩存的個數

      Qcache_total_blocks

  ⑻衡量緩存的有效性:命中率, hit/(hit+miss)

     常以 Qcache_hits/Com_select 的值作爲參考

     另外,也可參考 Qcache_hits/Qcache_inserts。如果此比值大於3:1, 說明緩存也是有效的;如果高於10:1,相當理想;

  ⑼緩存優化的思路:

   ①批量寫入比單次寫入對緩存的影響要小得多;

   ②緩存空間不宜過大,大量緩存的同時失效會導致MySQL假死;

   ③必要時,使用SQL_CACHE或SQL_NO_CACHE手動控制緩存;

   ④對寫密集型的應用場景,禁用緩存反而能提高性能

  ⑽碎片整理:FLUSH QUERY CACHE;

  ⑾清空緩存:RESET QUERY CACHE;

MariaDB [(none)]> show global variables like 'query_cache%';
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 16777216 |
| query_cache_strip_comments   | OFF      |
| query_cache_type             | ON       |
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+
6 rows in set (0.00 sec)

MariaDB [testdb]> show global status like 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 16757096 |
| Qcache_hits             | 8        |   #命中8次
| Qcache_inserts          | 41       |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 65       |
| Qcache_queries_in_cache | 2        |   #緩存中仍有兩個條目
| Qcache_total_blocks     | 6        |
+-------------------------+----------+
8 rows in set (0.00 sec)

MariaDB [testdb]> reset query cache;   #清空查詢緩存
Query OK, 0 rows affected (0.00 sec)

MariaDB [testdb]> show global status like 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 16759656 |
| Qcache_hits             | 8        |
| Qcache_inserts          | 41       |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 65       |
| Qcache_queries_in_cache | 0        |   #緩存中已沒有條目
| Qcache_total_blocks     | 1        |
+-------------------------+----------+
8 rows in set (0.00 sec)


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