Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
提高MySQL类查询的速度?_Mysql_Performance_Search - Fatal编程技术网

提高MySQL类查询的速度?

提高MySQL类查询的速度?,mysql,performance,search,Mysql,Performance,Search,对于具有自动完成功能的机场输入字段,当前有一个带有机场说明的表,autocomplete\u airport: lang | description (with INDEX) | ... -----+----------------------------------------------------+---- pt | New York - John F Kennedy (JFK), Estados Unidos | ... pt

对于具有自动完成功能的机场输入字段,当前有一个带有机场说明的表,
autocomplete\u airport

lang | description (with INDEX)                           | ...
-----+----------------------------------------------------+----
pt   | New York - John F Kennedy (JFK), Estados Unidos    | ...
pt   | Nova Iorque - John F Kennedy (JFK), Estados Unidos | ...
...
自动补全对单个单词有效。因此,当用户输入“yor”时,就会显示“newyork”(如果在LIMIT中)。查询当前的工作方式如下:

SELECT * FROM autocomplete_airport WHERE lang = "pt"
AND (description LIKE "%(yor)%"
     OR description LIKE "yor%"
     OR description LIKE "% yor%")
ORDER BY description
LIMIT 15
现在我想知道如何加快速度。一个想法是创建以下数据库结构,其中包含表
autocomplete\u airport
autocomplete\u airport\u word

id   | lang | description (with INDEX)                           | ...
-----+------+----------------------------------------------------+----
123  | pt   | New York - John F Kennedy (JFK), Estados Unidos    | ...
124  | pt   | Nova Iorque - John F Kennedy (JFK), Estados Unidos | ...
...

word (with INDEX) | autocomplete_airport_id
------------------+------------------------
New               |                     123
York              |                     123
John              |                     123
F                 |                     123
Kennedy           |                     123
JFK               |                     123
...
然后选择只需要在字符串开头搜索:

SELECT DISTINCT autocomplete_airport.*
FROM autocomplete_airport
INNER JOIN autocomplete_airport_word 
ON autocomplete_airport.id = autocomplete_airport_word.autocomplete_airport_id
WHERE lang = "pt"
AND word LIKE "yor%"
ORDER BY description
LIMIT 15
这个新结构值得费心吗?它真的会加速事情吗?有没有更简单的方法

更新 刚刚注意到单词表有一个缺陷。结果:搜索“纽约”不会有任何结果。什么应该起作用:

term (with INDEX)                               | autocomplete_airport_id
------------------------------------------------+------------------------
New York - John F Kennedy (JFK), Estados Unidos | 123
York - John F Kennedy (JFK), Estados Unidos     | 123
John F Kennedy (JFK), Estados Unidos            | 123
F Kennedy (JFK), Estados Unidos                 | 123
Kennedy (JFK), Estados Unidos                   | 123
(JFK), Estados Unidos                           | 123
Estados Unidos                                  | 123
Unidos                                          | 123
JFK                                             | 123

您提出的方法可能会加快查询速度。LIKE查询的重要一点是,通配符%不能位于模式的开头

如“%foobar”
不能使用索引。
比如“foobar%”
可以使用索引

然而,如果你只有几百个机场要存储,如果一次全表扫描真的那么痛苦,我会三思而后行

使用
EXPLAIN-select{rest of query}
了解数据库如何以及是否正在使用一个查询


(向下滚动到B树索引特征,这是默认的mysql索引类型)

正如MartinK所说,如果您的表只有几百行,那么即使不进行优化,您的查询也应该非常快速-值得检查发生了什么


但是,搜索文本字段的最佳方法是使用全文索引(http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html)-这正是为您描述的情况而设计的。

我不确定mysql全文索引功能。然而,“布尔全文搜索”(和*通配符)对于这个问题看起来确实有用。我有点担心“stopwords”和“stemming”(默认情况下未启用)可能会给用户带来一些意想不到的结果。YMMV。无论如何,向上投票:)看起来是最好的解决方案。不过,我还没有应用它,因为我首先需要客户的批准。在这种情况下,添加索引并不容易,因为整个数据库都是InnoDB(出于充分的理由),并且系统中没有提供将单个表更改为MyISAM的功能。尽管如此,我还是想了一个解决这个问题的方法。如果我理解正确,全文不能使用通配符,所以在我的工作中它是无用的case@MartinZvarík-如果您定义了您的案例,这会有所帮助,但是全文搜索实际上没有“通配符”的概念-但它支持在目标列中搜索querystring,而不管该querystring的位置如何。例如,请参阅。@NevilleKuyt我有像“SS2352”这样的随机字符,并且使用全文作为“*23*”没有发现任何好消息,知道像“%foobar”这样的
不能使用索引。实际上,这就是
EXPLAIN-select{rest-of-query}
所显示的。现在我在考虑是使用全文搜索还是我最初提出的单独单词表。顺便说一下,每个
lang
大约有10000个条目。应该做一些分析…通过“仅仅”添加一个索引和修改查询来解决它听起来非常诱人。我相信airport表中的数据是恒定的,所以MyIsam表可以在这里使用(您仍然可以不时地执行“锁定表”)。我要试一试。祝你好运