我有以下查询,需要300毫秒到450毫秒才能处理。
该表有大约300k行,大小为46 MB。
我创建了以下索引:
SELECT latitude, longitude, timezone
FROM geolocate WHERE
(LCASE(country) = 'cambodia' OR LCASE(countryiso) = 'cambodia')
AND
(
(LCASE(city) = 'kaôh préab' OR LCASE(cityabbr) = 'kaôh préab')
);
300毫秒我感觉时间太长了,但我不知道如何让它再加速。
我尝试创建单独的列索引无济于事。
如果有人能提供任何帮助,我会非常感激。
答案 0 :(得分:1)
假设表格中的列使用utf8
字符集及其默认排序规则utf8_general_ci
:
您不需要LCASE()
函数调用,因为MySQL已经使用了不区分大小写的比较。例如,将LCASE(country) = 'cambodia'
更改为country = 'cambodia'
。
将排序规则烘焙到索引中,因此如果存在索引,这将非常有效。
您的index2是不必要的,因为它也包含在index3中。
OR
操作的查询往往很慢。可以使用技巧来加速它们。
我无法确定您的索引是否正确。为此,您需要显示EXPLAIN结果和表定义。请read this note about asking good SQL questions,并注意有关查询效果的部分。
我会提供有关如何更改列定义的建议,但您没有向我们提供您的表定义。
答案 1 :(得分:0)
(O.Jones解释了摆脱LCASE
;我将在给定查询的上下文中解决OR
。)
计划A:让您的应用识别名称是完整还是缩写。如果您期望标准的双字母country_code,例如KH
,请检查输入的长度并构建相应的查询以避免OR
。 country_code
应为CHAR(2)
CHARACTER SET ascii`。
B计划:将OR
转为UNION
。使用原始查询,SELECTs
中需要4 UNION
。在计划A之后,你只能得到2。
计划C:拥有一个查找表,其中包含city
的所有变体 - 拼写,缩写,中文等。此表将映射到主表中使用的规范拼写。这样,您就可以避免OR
的{{1}}。
计划D:有一个额外的city
列,其中包含city,cityabbrev,country,countryabbrev。可能还有不同的拼写。使用TEXT
为此列编制索引。警告:“短语”存在问题;您应该将min token size设置为2以捕获country_code。