私は140000以上の行を持つテーブルでいくつかのSQLクエリを作成して展開するPerlスクリプトを書いています。MySQL - なぜこれらの2つのクエリでタイムスタンプが異なるパフォーマンスですか?
日付を比較して行を取得したいのですが、1つのSQLクエリを変更するだけで、実行速度が非常に異なることに気付きました。
100 $ SQLクエリを実行している次のテスト結果を見てください。 異なる実行間でスクリプト内で変更される唯一の行は$ sql行です。
私は何度もテストを実行しましたが、私はいつも同じような結果を得ています。だから、キャッシュの問題には関係していないと思います。 (mysqldumpをから取られた)テーブルが作成されたどのよう
my $sql = "SELECT `mem_used`, `swap_used`, `mem_total`
FROM `$config{db}{data_table}`
WHERE `host_id` = $host_id
AND date >= '$date'
AND TIMESTAMPDIFF(MINUTE , `date`, '$date') <= $interval;"; # VERY SLOW
time ./data_smoothing.pl
real 1m28.818s
user 1m6.516s
sys 0m0.256s
my $sql = "SELECT `mem_used`, `swap_used`, `mem_total`
FROM `$config{db}{data_table}`
WHERE `host_id` = $host_id
AND date >= '$date'
AND (UNIX_TIMESTAMP(`date`) - UNIX_TIMESTAMP('$date')) <= ($interval * 60);"; #SLOW
$ time ./data_smoothing.pl
real 0m10.005s
user 0m0.108s
sys 0m0.028s
my $sql = "SELECT `mem_used`, `swap_used`, `mem_total`
FROM `$config{db}{data_table}`
WHERE `host_id` = $host_id
AND (`date` BETWEEN '$date'
AND DATE_ADD('$date', INTERVAL $interval MINUTE));"; #FAST
$ time ./data_smoothing.pl
real 0m0.190s
user 0m0.084s
sys 0m0.016s
CREATE TABLE `data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`host_id` smallint(6) NOT NULL,
`date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`mem_total` double(10,3) DEFAULT NULL,
`mem_used` double(10,3) DEFAULT NULL,
`swap_total` double(10,3) DEFAULT NULL,
`swap_used` double(10,3) DEFAULT NULL,
`CPU_count` smallint(6) DEFAULT NULL,
`load_avg_1` float DEFAULT NULL,
`load_avg_5` float DEFAULT NULL,
`load_avg_15` float DEFAULT NULL,
`uptime` double(10,3) DEFAULT NULL,
`cpuIdlingTime` double(10,3) DEFAULT NULL,
`rxBytesTotal` bigint(20) DEFAULT NULL,
`txBytesTotal` bigint(20) DEFAULT NULL,
`rxPacketsTotal` bigint(20) DEFAULT NULL,
`txPacketsTotal` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`,`host_id`),
KEY `fk_data_hosts` (`host_id`),
KEY `date_memtot_hosts` (`date`,`mem_total`,`host_id`),
CONSTRAINT `fk_data_hosts` FOREIGN KEY (`host_id`) REFERENCES `hosts` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=145300 DEFAULT CHARSET=utf8;
私は見て..良い説明をありがとう! –
Vの場合、このタイプのQを助けるために常にEXPLAINを試してください。この場合、クエリエンジンは 'date'の間に' date_memtot_hosts'を使用できますので、(1)のように全テーブルスキャンを行う必要はありません(2)のようにパーツテーブルスキャンを実行します。 * hot *クエリの場合は、テーブルの(host_id、date)に追加のキーを追加して3を試してください。これはシャベルのようなものです。 – TerryE
EXPLAINコマンドについてのヒントがありませんでした。ありがとうございました! –