zoukankan      html  css  js  c++  java
  • MySQL InnoDB 引擎的持久性与性能

    MySQL 事务的 ACID 特性中,D 代表持久性(Durability):在使用 InnoDB 引擎时,当返回客户端一个成功完成事务的确认时, InnoDB 就会保证数据的一致性,即使该数据在此时还没有写入磁盘,因为 InnoDB 引擎的重做日志已经连续地记录了已完成的事务。InnoDB 不是在事务执行的时候直接将数据写入磁盘,即不会立即将更新的数据写入磁盘,而是由 InnoDB 存储引擎的后台 worker 线程负责执行。可以根据在配置文件中的配置来设置日志写入磁盘的频率,默认情况下是每次事务会刷写到磁盘一次。

     不同的持久性设置会对数据库的性能产生很大的影响,默认情况下配置文件 my.ini 或 my.cnf 中 innodb_flush_log_at_trx_commit 的值为 1:

    mysql> select @@global.innodb_flush_log_at_trx_commit;
    +-----------------------------------------+
    | @@global.innodb_flush_log_at_trx_commit |
    +-----------------------------------------+
    |                                       1 |
    +-----------------------------------------+

    不同的设置会改变 InnoDB 的持久性和性能,该选项有 3 个值:

    1(默认) 对于每个事务日志,InnoDB 都会把日志写入(write)并刷写(flush)到磁盘。速度最慢,但是最持久
    2 InnoDB 将所有发生的事务日志写入(write)磁盘,并且每秒对这些数据刷写(flush)一次
    0 InnoDB将最近一秒中所发生的所有事务日志写入(write)磁盘,然后将这些日志刷写(flush)到磁盘。

    (写日志在 write 时发生 ,写入数据文件到磁盘在操作系统 flush buffer 时发生)

    在一些场景下可以通过破坏真正的持久性来显著提高性能。

    测试一下 MyISAM 引擎、 InnoDB 引擎(不同持久性下)的插入速度。

    测试环境:

    CentOS6.6 64-bit/2G

    MySQL 5.6.29

    mysql> select version();
    +------------+
    | version()  |
    +------------+
    | 5.6.29-log |
    +------------+

    PHP 7.0.7

    [root@localhost test]# php -v
    PHP 7.0.7 (cli) (built: Feb 11 2017 16:47:30) ( NTS )
    Copyright (c) 1997-2016 The PHP Group
    Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies

    表结构:

    MyISAM

        CREATE TABLE `m` (
            `id` int(10) NOT NULL AUTO_INCREMENT,
            `number` int(10) NOT NULL DEFAULT '0',
            PRIMARY KEY (`id`)
        ) ENGINE=MyISAM DEFAULT CHARSET=latin1

    InnoDB

        CREATE TABLE `i` (
            `id` int(10) NOT NULL AUTO_INCREMENT,
            `number` int(10) NOT NULL DEFAULT '0',
            PRIMARY KEY (`id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=latin1

    PHP 文件:

    <?php 
    
    set_time_limit(0);
    
    $host       = 'localhost';
    $user       = 'root';
    $pwd        = 'root';
    $database   = 'test';
    
    $mysqli = new mysqli($host, $user, $pwd, $database);
    if($mysqli->connect_error)
    {
        die('Connect Error: '.$mysqli->connect_error);
    }
    
    $table_name = 'example_myisam';
    // $table_name = 'example_innodb';
    $times = 10000;
    
    $sql_truncate   = "TRUNCATE TABLE {$table_name}";
    $mysqli->query($sql_truncate);
    
    $time = -microtime(true);
    for($i = 0; $i < $times; $i++)
    {
        $sql = "INSERT INTO {$table_name} (`number`) VALUES ({$i})";
        if(false === $mysqli->query($sql))
        {
            die('ERROR: '.$mysqli->error);
        }
    }
    $time += microtime(true);
    echo '用时',$time,'秒';

    分别测试 1w 条数据和 10w 条数据不同情况下所耗费的时间:

       MyISAM  InnoDB.innodb_flush_log_at_trx_commit =1 InnoDB.innodb_flush_log_at_trx_commit =2  InnoDB.innodb_flush_log_at_trx_commit =0 
       第1次 第2次  第3次  平均  第1次  第2次  第3次  平均  第1次  第2次  第3次  平均  第1次  第2次  第3次  平均 
     1w  0.697s  0.722s 0.822s   0.747s  18.204s  19.012s  17.173s  18.130s  0.842s  0.871s  1.058s  0.924s  0.796s 0.795s   0.966s  0.852s
    10w   6.579s  6.421s 6.703s  6.568s  201.111s  198.429s  140.926s  180.155s  9.208s  9.566s  9.068s  9.281s  8.022s  7.838s  7.918s  7.926s
  • 相关阅读:
    Tomcat 跨域问题的解决
    [SheetJS] js-xlsx模块学习指南
    漂亮又好用的Redis可视化客户端汇总
    Visual Studio 2015 出现 NuGet 安装程序包错误解决方法
    vs2015使用nuget包管理器安装失败
    C# 尝试还原程序包是出错:找不到“XXXXX”版本的程序包“XXXXXX”
    基于flink和drools的实时日志处理
    Docker常用命令
    Laravel5打印所有运行SQL
    Laravel5版本在sql查询时用when方便条件判断查询【闭包方式】
  • 原文地址:https://www.cnblogs.com/dee0912/p/6244732.html
Copyright © 2011-2022 走看看