このスクリプトの実行時間を短縮しようとしています。ループで約 1000 回、約 200 万レコードのデータベースにクエリを実行します。
foreach ($ids as $id){
$stmt=$dbh->query("SELECT SQL_CACHE * FROM `ids`
WHERE $id BETWEEN `id_start` AND `id_end`");
$rows[] = $stmt->fetch();
}
4 コアの 8 GB マシンでは永遠にかかります (約 800 秒!)。ID グループは重複せず、ID は実行ごとにいくつかの異なるグループからのものになる傾向があり、(id_start,id_end) と (id_end) の両方にインデックスを付けました。
キャッシュは状況を非常に改善します (同じ 1000 個の値を複数回実行するのはほんの数秒です) が、キャッシュされていないクエリを高速化するために何ができるか知りたいです。
EXPLAIN の出力例:
"id" "select_type" "table" "type" "possible_keys" "key" "key_len" "ref" "rows" "Extra"
"1" "SIMPLE" "ids" "range" "id_start,id_end" "id_start,id_end" "5" "" "52508" "Using index condition"
編集:「インデックス条件を使用する」の代わりに、「どこを使用するか」が表示されることがあります(よくわかりませんが、840771583 よりも高い ID 値からだと思います)なぜですか?
編集 2 : 完全な作成コード:
CREATE TABLE `ids` (
`id_start` INT(10) UNSIGNED NULL DEFAULT NULL,
`id_end` INT(10) UNSIGNED NULL DEFAULT NULL,
`iso-639-1` VARCHAR(2) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`country_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`region_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`city_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`area_code` VARCHAR(16) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`timezone` VARCHAR(6) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
UNIQUE INDEX `id_startid_end` (`id_start`, `id_end`),
INDEX `id_end` (`id_end`),
INDEX `country_name` (`country_name`),
INDEX `region_name` (`region_name`),
INDEX `city_name` (`city_name`),
INDEX `area_code` (`area_code`),
INDEX `iso-639-1` (`iso-639-1`),
INDEX `timezone` (`timezone`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB;