0

他の多くの SO 投稿と MySQL ドキュメントを確認しましたが、インデックスが使用されていない理由と、インデックスを強制的に使用する方法についての回答が得られないようです。他の多くの人が同様の問題を抱えていることがわかりますが、解決策が見つかりません。

テーブルはこんな感じ

CREATE TABLE `countries_ip` (
`ipfrom` INT(10) UNSIGNED ZEROFILL NOT NULL,
`ipto` INT(10) UNSIGNED ZEROFILL NOT NULL,
`countrySHORT` CHAR(2) NULL DEFAULT NULL,
`country_id` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`ipfrom`, `ipto`, `country_id`),
INDEX `from_to_index` (`ipfrom`, `ipto`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

なぜ「from_to_index」があるのか​​ わかりません-私には冗長に思えます。とにかく、 EXPLAIN クエリは次のようになります

EXPLAIN SELECT *
        FROM track_report t, countries_ip ip
        WHERE t.ip BETWEEN ip.ipfrom AND ip.ipto

EXPLAIN の結果は次のとおりです。

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  t   ALL getwebmaster    NULL    NULL    NULL    36291   
1   SIMPLE  ip  ALL PRIMARY,from_to_index   NULL    NULL    NULL    153914  Range checked for each record (index map: 0x3)

ご覧のとおり、countries_ipテーブルの PRIMARY KEY は使用されていないため、クエリに長い時間がかかります ( countries_ip15 万件を超えるレコードがあります) 。

おそらく単純なものが欠けていますが、このクエリを最適化する方法についてアドバイスをいただければ幸いです。前もって感謝します。

4

1 に答える 1

1

にインデックスを定義すると役立つ場合がありますtrack_report.ipSQL フィドルを参照してください。

明示的な比較を行うように where 句を変更したため、from_to_index が使用されるようになりました。

SELECT ip
FROM track_report t, countries_ip ip
where t.ip >= ip.ipfrom and t.ip <= ip.ipto

SQL フィドルを参照してください。

于 2012-12-11T11:26:52.977 に答える