一、存儲引擎
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會立刻返回結果,而跳過分析、優化和執行階段。
⑵緩存的內容是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)