私はInnoDB MySql Geo IDテーブルを100万行以上持っています。一種類のみのクエリがありますこのMySQLテーブルを1つのクエリでさらに最適化する方法
CREATE TABLE `geoid` (
`start_ip` int(11) NOT NULL,
`end_ip` int(11) NOT NULL,
`city` varchar(64) NOT NULL,
`region` char(2) NOT NULL,
PRIMARY KEY (`start_ip`,`end_ip`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
このテーブルに対して実行しました::テーブルの構造はこれですこのクエリは、超遅いが、信じられないほど高速ではないではありません〜0.4228秒、程度かかり
SELECT city, region FROM geoid WHERE 1259650516 BETWEEN start_ip AND end_ip
エーテル。
私の質問は:どのように私はさらに、この単一のクエリのための私のテーブルを最適化することができますか?
は、私は、次のことを試してみました:
- 変更のMyISAMのストレージエンジンは、これは、クエリが約1.9秒かかりました。
- は 'geoid.start_ip < = 1259650516と1259650516 < = geoid.end_ip' WHEREステートメントを使用します。しかし、それは0.4秒の代わりに約0.5秒かかる。
私はそれを小さくするテーブルからすべての無用の行を削除しました。私はすべて100万行が必要です。
UPDATE/SOLUTION以下の記事へ
おかげで、ここで私は、この問題を修正するために何をしたかです。 (単に興味のある誰のためにこの答えを完了するために)
私は上記の表に新しい列を追加しました:
ALTER TABLE `geoid` ADD `geoip` LINESTRING NOT NULL
を私はその後、start_ipから地理データを新しい列を充填し
GeomFromText(CONCAT('LINESTRING(', start_ip, ' -1, ', end_ip, ' 1)'))
をend_ip私はすべて、そこから新しい列
CREATE SPATIAL INDEX geoip_index ON geoid(geoip);
に空間索引を作成し
クエリを次のように変更する必要があります。
SELECT city, region FROM geoid WHERE MBRContains(geoip, GeomFromText(CONCAT('POINT(', 1259650516, ' 0)')));
そして完了しました。これにより、クエリーが0.42秒から0.0003秒にダウンしました!!!!!!!
私はこのINDEXが大好きです。ありがとうございました。それが役に立てば幸い。
あなたは' SPATIAL'インデックスを作成した上で一つのインデックスを作成しますか? – Quassnoi
まずそれをMyISAMに変換しました。 – RonSper