[Node.js+MySQL]Blob型に対してインデックスは効果があるのか? ?
2019.03.19
こんにちは、千田です。
3月も中旬に差しかかかり、世のサラリーマンの方々の多くは決算月という事で大変慌ただしい毎日を
お過ごしなのかなと思います。
スワローの決算は11月なので、世のサラリーマンの方々よりは比較的落ち着いているのかなと思うので、
(仕事はちゃんとやってますよ!!)
今のうちに実験的な事も1つ、2つやりたいなーと思う今日この頃です。
という訳で(めちゃくちゃ唐突ですが)、今回は個人的に気になっていた
「Blob型に対してインデックスは効果があるのか」
というのを検証してみたいと思います。
検証方法
- 画像をBase64エンコードしてBlob型のカラムに登録する
- Blob型のカラムにインデックスを作成する前と作成した後で検索時間を比較する
環境
端末:MacBook Pro
CPU:2.3 GHz Intel Core i5
メモリ:16 GB 2133 MHz LPDDR3
MySQL バージョン:5.7.24
Node.jsバージョン:10.15.1
事前準備
テーブルの作成
では、まずは検証用のテーブルを作成します。インデックスはまだ作成しません。
1 2 3 4 5 6 | CREATE TABLE images( id INT NOT NULL AUTO_INCREMENT, image longblob, file_name VARCHAR(256), PRIMARY KEY (id) ); |
file_nameには確認用に元のファイル名を入れてます。
Blobデータの準備
テーブルを作ったら画像データをBase64にエンコードしてINSERTしていきます。
今回は登録用にNode.jsで下記のようなスクリプトを作成しました。
regist.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | const fs = require('fs'); const db = require('mysql'); const imageDir = 'images/'; const config = { host: '127.0.0.1', user: 'xxxx', password: 'xxxxx', database: 'xxxxx', insecureAuth: true, }; const con = db.createConnection(config); let sql = 'insert into images (image,file_name) values '; fs.readdir(imageDir, (err, files) => { if (err) { console.log('directory read error'); } else { files.forEach((file) => { fs.readFile(imageDir + file, 'base64', (err, data) => { if (err) { console.log('file read error'); } else { let val = '(' + db.escape(data) + ',' + db.escape(file) + ')'; con.query(sql + val,(err, results, fields) => { if (err) { console.log(err); console.log('db error'); } }); } }); }); } }); |
それではスクリプトを実行します。
1 | $ node regist.js |
はい、これでBlobデータの準備ができました!
検証
データの準備ができたので、早速検証していきます!
前提条件
- レコード数:約31650件
- DBの場所:localhost
検証用スクリプトの準備
検証用のスクリプトもNode.jsで準備します。
search.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | const fs = require('fs'); const db = require('mysql'); const imageDir = 'images/'; const imageFile = '[検索するファイル名]'; const config = { host: '127.0.0.1', user: 'xxxx', password: 'xxxxxxx', database: 'xxxxxx', insecureAuth: true, }; const con = db.createConnection(config); fs.readFile(imageDir + imageFile, 'base64', (err, data) => { if (err) { console.log('file read error'); } else { // 検索開始 console.time('処理時間'); con.query('select * from images where image = ' + db.escape(data) , (err, results, fields) => { // 検索終了 console.timeEnd('処理時間'); if (err) { console.log(err); console.log('db error'); } else { results.forEach((r) => { console.log(r.id); }); } }); } }); |
計測 その1(インデックスなし)
では、早速スクリプトを実行して計測してみます。
1 2 | $ node search.js 処理時間: 8547.065ms |
1回目 | 8547.065ms |
2回目 | 8506.852ms |
3回目 | 8465.807ms |
うーん、思った以上に時間がかかった印象です。。。こんなものなんですかね?
果たしてインデックスを作成するとどの程度変わるのか??
インデックスの作成
期待を込めて、インデックスを作成します。
1 | ALTER TABLE images ADD INDEX idx_image(image(255)); |
計測その2(インデックスあり)
インデックスを作成したところで、早速検証します。
果たしてどの程度変わるのか??
1 2 | $ node search.js 処理時間: 75.239ms |
1回目 | 75.239ms |
2回目 | 62.911ms |
3回目 | 60.580ms |
なんと結果としては10分の1以下に短縮されました。こんなにも変わるものなのですね!!
総括
というわけで、結果は一目瞭然で「効果あり」でした!
それでは!
↓↓↓ぜひチェックしてください
~提供中のヒューマンセンシング技術~
◆人物検出技術
歩行者・来店者数計測やロボット搭載も
https://humandetect.pas-ta.io
◆視線検出技術
アイトラッキングや次世代UIに
https://eyetrack.pas-ta.io
◆生体判定技術
eKYC・顔認証のなりすまし対策を!
https://bio-check.pas-ta.io
◆目検出技術
あらゆる目周りデータを高精度に取得
https://pupil.pas-ta.io
◆音声感情認識技術
会話から怒りや喜びの感情を判定
https://feeling.pas-ta.io
◆虹彩認証技術
目の虹彩を利用した生体認証技術
https://iris.pas-ta.io