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)


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