最近在考慮將公司某些專案的排程改到 node.js 上面,主要是程式本體的 driver 跟 MySQL 之間的效能,先講結論,如果有用 MVC 的人不要用內建的 ORM 跑大資料寫入的排程,雖然 ORM 慢是大家都知道的事情,畢竟他本來就是圖方便的工具,但沒想到大量資料寫入他可以慢到將近一倍,本測試執行 node.js、PHP PDO,一次跑 3000 個 insert 各跑十次,以下是寫法以及結果。
環境說明
- PHP 5.6.15
- MySQL Ver 15.1 Distrib 10.1.9-MariaDB
- node.js 5.8.0
- Windows 7 64bit
- 8GB Ram
套件說明
程式寫法
node.js
console.time('add');
console.log('start');
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : '',
password : '',
database : 'test',
});
var length = process.argv[2] || 100;
var counter = 1;
connection.connect();
var add = (counter) => {
connection.query('INSERT INTO `users` SET ?', {name: 'test'}, (err, rows, fields) => {
if (err) {
console.log(err);
}
if (counter < length) {
add(++counter);
} else {
console.log('all done');
console.timeEnd('add');
connection.end();
}
});
};
add(counter);
PHP PDO
<?php
include 'vendor/autoload.php';
echo 'start'.PHP_EOL;
use TimeBenchmark\Stopwatch;
$length = isset($argv[1]) ? $argv[1] : 100;
$counter = 1;
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8';
$db = new PDO($dsn, '');
$stopwatch = Stopwatch::create();
$stopwatch->start();
$add = function($counter) use ($length, $db, $stopwatch, &$add) {
$sql = "INSERT INTO `users`(`name`) VALUES(:name)";
$stmt = $db->prepare($sql);
$stmt->bindValue(':name', 'test');
$stmt->execute();
if ($counter < $length) {
$add(++$counter);
} else {
$stopwatch->stop();
echo $stopwatch->getElapsedMilliseconds().'ms'.PHP_EOL;
}
};
$add($counter);
測試結果
node.js
- 75500.335ms
- 76234.479ms
- 60025.145ms
- 68833.407ms
- 71067.471ms
- 63238.021ms
- 63908.226ms
- 57938.820ms
- 66872.004ms
- 66817.116ms
PHP PDO
- 63311.331ms
- 66825.682ms
- 67424.741ms
- 67320.732ms
- 62134.213ms
- 65586.558ms
- 67117.711ms
- 54427.443ms
- 66046.604ms
- 67741.773ms
結論
其實數據沒有差很多,但 node.js 比較會飄,所以還是觀察一下吧。