~ 1 milyon satır içeren bir InnoDB MySql Geo ID tablom var. Tablo yapısını şudur:Tek bir Sorgu için bu MySQL tablomun daha da iyileştirilmesi
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;
Sadece bir tip sorgu bu tabloya karşı ran olacaktır:
SELECT city, region FROM geoid WHERE 1259650516 BETWEEN start_ip AND end_ip
Bu sorgu yaklaşık ~ 0,4228 sn sürer, süper yavaş ama inanılmaz derecede hızlı değil değil eter.
Soruma soru: Tabloyu bu tek sorgu için nasıl daha da optimize edebilirim?
Aşağıdaki şeyler denedim:
- Değişim MyISAM için Depolama Motoru, bu sorgu yaklaşık 1.9 sn almak yaptı.
- WHERE ifadesini kullanın 'WHERE geoid.start_ip < = 1259650516 VE 1259650516 < = geoid.end_ip'. Ama bu .4 ish yerine yürütmek için yaklaşık 5 saniye sürer.
Daha az yapmak için tüm gereksiz satırları tablodan kaldırdım. 1 milyonun hepsine ihtiyacım var. Aşağıdaki yazıya
GÜNCELLEME/ÇÖZÜM
sayesinde burada ben bu sorunu çözmek için bunu yaptı.
Yukarıdaki tabloya yeni bir sütun eklendi (sadece başka ilgilenen herkes için bu cevabı tamamlamak için): Sonra start_ip coğrafi verileri ile yeni bir sütun doluALTER TABLE `geoid` ADD `geoip` LINESTRING NOT NULL
ve end_ip
GeomFromText(CONCAT('LINESTRING(', start_ip, ' -1, ', end_ip, ' 1)'))
sonra hepsi Oradan
CREATE SPATIAL INDEX geoip_index ON geoid(geoip);
yeni sütun üzerinde kayma dizin yarattı
SELECT city, region FROM geoid WHERE MBRContains(geoip, GeomFromText(CONCAT('POINT(', 1259650516, ' 0)')));
VE YAPILDI: Eğer sorgunuzu değiştirecek mi yapmak zorundayız. Bu sorguyu .42 sn'den .0003 sn'ye düşürdü !!!!!!!
Bu INDEX'i seviyorum. Teşekkür ederim. Umarım yardımcı olur.
Bir 'InnoDB' tablosunda bir 'SPATIAL' indeksi oluşturdunuz? – Quassnoi
İlk önce MyISAM'a dönüştürdüm. – RonSper