いつもお世話になっております。
大量のデータ(1億とか)から1件のデータを検索する際に何かしら早く検索する方法はないのか知りたくて質問をさせて頂きます
SQL
1CREATE TABLE IF NOT EXISTS `serials` ( 2 `id` int(11) NOT NULL auto_increment, 3 `serial_code` char(12) BINARY NOT NULL, 4 PRIMARY KEY (`id`), 5 UNIQUE KEY `serial_code` (`serial_code`) 6) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
このテーブルにcsvデータの流し込みで1億件のデータがあるとします。
普通に
SQL
1SELECT * FROM `serials` where serial_code=1111111111111;
で検索すると検索に時間がかかってしまいます。explainで確認したところ
+----+-------------+---------+-------+---------------+------------+---------+------+----------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+-------+---------------+------------+---------+------+----------+--------------------------+ | 1 | SIMPLE | serials | index | serial_code |serial_code | 36 | NULL | 40413015 | Using where; Using index | +----+-------------+---------+-------+---------------+------------+---------+------+----------+--------------------------+
typeがindexとなりフルスキャンではないですがやはり遅くはなってしまいます。
これをidで検索すると一瞬で表示され、typeもconstになります。
だいたい大量のデータから検索する場合はINDEXを貼るのが有効みたいな記事をよく見るのですが、number
をユニークキーに設定しているのでINDEXを貼っている認識ですが間違いないでしょうか?
また何か出来る設定でnumber
の検索を早く出来る方法があればご教授頂きたいと思います。
なお、実際はPHPでシステムを組んでいて、シリアルナンバーをフォームで入力してそのシリアルがserials
テーブルとserial_registration_histories
テーブルに存在しているかどうかのチェックを行っています。ですので
SQL
1CREATE TABLE IF NOT EXISTS `serials` ( 2 `id` int(11) NOT NULL auto_increment, 3 `serial_code` char(12) BINARY NOT NULL, 4 PRIMARY KEY (`id`), 5 UNIQUE KEY `serial_code` (`serial_code`) 6) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 7 8CREATE TABLE IF NOT EXISTS `serial_registration_histories` ( 9 `id` int(11) NOT NULL auto_increment, 10 `serial_id` int(11) NOT NULL, 11 `created` datetime default NULL, 12 `modified` datetime default NULL, 13 PRIMARY KEY (`id`), 14 UNIQUE KEY `serial_id` (`serial_id`) 15) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
このテーブルにserials
テーブルにはデータを流し込み、serial_registration_histories
にはserials
テーブルには存在して
SELECT文
1`serial_registration_histories`にはないシリアル情報を格納するデータが存在しているのですが、この複数のテーブルに対して 2SELECT `Serial`.`id`, `SerialRegistrationHistory`.`id` FROM `テーブル名`.`serials` AS `Serial` LEFT JOIN `テーブル名`.`serial_registration_histories` AS `SerialRegistrationHistory` ON (`Serial`.`id` = `SerialRegistrationHistory`.`serial_id`) WHERE `Serial`.`serial_code` = '719653552612' LIMIT 1
このSQLを投げています。このSQLが遅くならなければいいのですが、これをexplainをつけると
+----+-------------+---------------------------+-------+---------------+------------+---------+-------+------+----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------------------------+-------+---------------+------------+---------+-------+------+----------------------+ | 1 | SIMPLE | Serial | const | serial_code | serial_code| 36 | const | 1 | Using index | | 1 | SIMPLE | SerialRegistrationHistory | const | serial_id | serial_id | 4 | const | 0 | unique row not found | +----+-------------+---------------------------+-------+---------------+------------+---------+-------+------+----------------------+
このような結果になってtypeがconstになっているのでそこまで遅くならないとは思うのですが正直なんで単純なsqlはindexでこれがconstになっているのか不明です。
質問が多くなって申し訳ありませんが、よろしくお願いします
※修正点
命名が良くないと指摘を受けたので修正しました。(number→serial_code)
頂いた回答から上半分の単純なSELECT文の検索が遅いと言う点は型変換を行って検索を行っているので遅いというのがわかりましたので解決済みです。

回答4件
あなたの回答
tips
プレビュー