我需要使用 PHP 和 jQuery 进行实时搜索,从两个表中选择城市和国家 cities
(近 300 万行)和 countries
(几百行)。
有一小会儿我正在考虑使用 MyISAM
表 cities
如InnoDB
不支持FULLTEXT
搜索,但决定这不是一个可行的方法(频繁表崩溃,所有其他表都是 InnoDB
等,并且 MySQL 5.6+ InnoDB
也开始支持 FULLTEXT
索引)。
所以,现在我仍然使用 MySQL 5.1,并且大多数城市仅由一个单词或最多 2-3 个单词组成,但是例如“纽约”——大多数人如果指的是“纽约”,就不会搜索“York”。所以,我只是在 city_real
上放置了一个索引列(这是一个 varchar)。
以下查询(我在不同版本中尝试过,没有任何 JOIN
和没有 ORDER BY
,有 USE INDEX
,甚至有 FORCE INDEX
,我尝试过 LIKE 而不是等于(=),但另一篇文章说 =速度更快,如果通配符仅在末尾,则可以使用它),在 EXPLAIN
中它总是说“使用位置,使用文件排序”。查询的平均时间约为 4 秒,您必须承认对于实时搜索来说有点慢(用户在文本框中键入并查看城市和国家的建议)...
如果用户输入至少 3 个字符,则实时搜索 (jQuery ajax) 会进行搜索...
SELECT ci.id, ci.city_real, co.country_name FROM cities ci LEFT JOIN countries co ON(ci.country_id=co.country_id) WHERE city_real='cit%' ORDER BY population DESC LIMIT 5
有一个PRIMARY
上ci.id
和一个INDEX
上ci.city_real
。知道为什么 MySQL 不使用索引吗?或者我怎样才能加快查询速度?或者我应该/不应该在哪里设置 INDEX
?
预先非常感谢您的帮助!
这是解释输出
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE ci range city_real city_real 768 NULL 1250 Using where; Using filesort
1 SIMPLE co eq_ref PRIMARY PRIMARY 6 fibsi_1.ci.country_id 1
最佳答案
您应该使用 WHERE city_real LIKE 'cit%'
,而不是 WHERE city_real='cit%'
。
I have tried LIKE instead equal (=) but another post said = was faster and if the wildcard is only at the end, it is OK to use it
这是错误的。 =
不支持通配符,因此会给您错误的结果。
Or how I could speed up the query?
确保两个表中都有 country_id
索引。如果您需要进一步帮助,请发布 EXPLAIN SELECT ...
的输出。
关于MySQL 不使用索引(尽管有 FORCE INDEX),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10374398/