MySQL InnoDB 引擎的持久性與性能

MySQL 事務的 ACID 特性中,D 表明持久性(Durability):在使用 InnoDB 引擎時,當返回客戶端一個成功完成事務的確認時, InnoDB 就會保證數據的一致性,即便該數據在此時尚未寫入磁盤,由於 InnoDB 引擎的重作日誌已經連續地記錄了已完成的事務。InnoDB 不是在事務執行的時候直接將數據寫入磁盤,即不會當即將更新的數據寫入磁盤,而是由 InnoDB 存儲引擎的後臺 worker 線程負責執行。能夠根據在配置文件中的配置來設置日誌寫入磁盤的頻率,默認狀況下是每次事務會刷寫到磁盤一次。php

 不一樣的持久性設置會對數據庫的性能產生很大的影響,默認狀況下配置文件 my.ini 或 my.cnf 中 innodb_flush_log_at_trx_commit 的值爲 1:mysql

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

不一樣的設置會改變 InnoDB 的持久性和性能,該選項有 3 個值:sql

1(默認) 對於每一個事務日誌,InnoDB 都會把日誌寫入(write)並刷寫(flush)到磁盤。速度最慢,可是最持久
2 InnoDB 將全部發生的事務日誌寫入(write)磁盤,而且每秒對這些數據刷寫(flush)一次
0 InnoDB將最近一秒中所發生的全部事務日誌寫入(write)磁盤,而後將這些日誌刷寫(flush)到磁盤。

(寫日誌在 write 時發生 ,寫入數據文件到磁盤在操做系統 flush buffer 時發生)數據庫

在一些場景下能夠經過破壞真正的持久性來顯著提升性能。性能

 

測試一下 MyISAM 引擎、 InnoDB 引擎(不一樣持久性下)的插入速度。測試

測試環境:ui

CentOS6.6 64-bit/2Gspa

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
相關文章
相關標籤/搜索