自动填充城市列表查询花费太多时间加载到巨大的城市表

时间:2011-01-24 12:24:25

标签: php mysql doctrine

我有一张有近1,600,000条记录的城市表。我有一个自动填充文本框,我有查询来获取城市数据,国家/地区数据如下:

SELECT m.idmetrocenter, m.idcountry, m.metrocentername, 
c.idcountry, c.countryname FROM metrocenter m 
INNER JOIN country c ON m.idcountry = c.idcountry 
WHERE (m.metrocentername like "ap%" OR c.countryname like "ap%") 
ORDER BY m.metrocentername, c.countryname 
LIMIT 10

此查询需要更多时间进行响应,其响应时间几乎为110秒。 我在idmetrocenter,idcountry,metrocentername,countryname上创建了索引。即便如此,这种反应也很糟糕。

任何人都可以帮助我实现更快的输出。我目前正在使用学说。如果有人能让我知道,学说中的解决方案会更好。

提前致谢

3 个答案:

答案 0 :(得分:1)

首先尝试explain您的查询,看看是否有效使用了索引:

mysql> EXPLAIN SELECT m.idmetrocenter AS m__idmetrocenter, m.idcountry AS m__idcountry, m.metrocentername AS m__metrocentername, c.idcountry AS c__idcountry, c.countryname AS c__countryname FROM metrocenter m INNER JOIN country c ON m.idcountry = c.idcountry WHERE (m.metrocentername like "ap%" OR c.countryname like "ap%") ORDER BY m.metrocentername, c.countryname LIMIT 10 \G

第二: 尝试将LIKE语句更改为全文搜索(MATCH/AGAINSThttp://dev.mysql.com/doc/refman/5.5/en/fulltext-search.html

答案 1 :(得分:0)

除了像Francesco建议的那样使用FTS,您还可以使用内置的Doctrines search behaviour。这只是建立一个索引,其中包含已定义列的所有单词,并以高效快捷的方式访问它们。

如果你无法建立/使我们成为FTS,这就是你要走的路。

答案 2 :(得分:0)

当您执行JOINS时,您必须执行Cartesian product。这是非常昂贵的,你应该避免它。

在这个时代你应该忘记data normalization。正如来自Flickr的Cal Henderson所说:“normalised data is for sissies”(第41页,共41页)。它使搜索更快。这些幻灯片非常好,并且有很多好的信息。因此,在41的第24张幻灯片中,他们说他们没有使用LIKE,因为它很慢。他们使用FULLTEXT索引(幻灯片25中的41)。

另外我认为您应该使用redis缓存the data(autocomplete) in memory以加快您的网站速度。如果您无法编译源代码(redis,如果您可以编译phpredis,或者只是简单的php版本=> predis)。然后你甚至可以使用Redis To Go的免费计划。 Redis是fast!