场景:我有一个表单,使用对后端的AJAX调用自动建议用户输入文本。进行调用,并在键入表单输入字段的每个字符上运行查询。该查询正在查找零售地点名称,零售地点城市或州(位于另一个表中,按指定的ID加入)
表:(这些表中有更多字段,但为了简洁起见......)
bbl_locations
id
name
city
state_id
bbl_states
id
name
bbl_location index:
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
| bbl_locations | 0 | PRIMARY | 1 | id | A | 1 | NULL | NULL | | BTREE | | |
| bbl_locations | 0 | name | 1 | name | A | 1 | NULL | NULL | YES | BTREE | | |
bbl_states index:
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
| bbl_states | 0 | PRIMARY | 1 | id | A | 54 | NULL | NULL | | BTREE | | |
| bbl_states | 0 | abbreviation | 1 | abbreviation | A | 54 | NULL | NULL | YES | BTREE | | |
| bbl_states | 0 | name | 1 | name | A | 54 | NULL | NULL | YES | BTREE | | |
| bbl_states | 1 | country_id | 1 | country_id | A | 54 | NULL | NULL | | BTREE | | |
查询:(在密苏里州寻找零售商 - 请记住,只要我输入' M')它就会真正运行。
SELECT l.id
, l.name
, l.division
FROM bbl_locations l
JOIN bbl_states s
ON l.state_id = s.id
WHERE l.name LIKE '%missouri%'
OR l.city LIKE '%missouri%'
OR s.name LIKE '%missouri%'
查询说明:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | SIMPLE | bbl_locations | ALL | NULL | NULL | NULL | NULL | 1 | |
| 1 | SIMPLE | bbl_states | eq_ref | PRIMARY | PRIMARY | 2 | database.bbl_locations.state_id | 1 | Using where |
我的问题:我可以做些什么来提高此查询的速度(目前正在执行:0.26)?有没有更好的方法来索引或执行上述查询?
奖金问题:假设我使用PDO抽象层,转义输入并绑定值,是否有人看到此查询存在安全问题?
无论如何,假设多个人同时访问此搜索并输入任何可能的字符组合,我可以看到这变得非常缓慢且资源密集,并且希望尽可能地减轻这种情况。谢谢!!!
[UPDATE] 根据以下评论,我已将查询更新为以下内容:
SELECT l.id
, l.name
, l.division
FROM bbl_locations l
LEFT JOIN bbl_states s
ON l.state_id = s.id
WHERE l.name LIKE 'missouri%'
OR l.city LIKE 'missouri%'
OR s.name LIKE 'missouri%'
现在零售商的州数据集很小甚至更小,所以我没有注意到任何差异,执行时间和以前一样徘徊在相同数量。在EXPLAIN中,它显示正在使用的其他索引。手指交叉。 谢谢给大家的帮助,我真的很感激,如果我能给你积分,我会这样做。
如果还有其他任何方法可以提高此查询的速度或安全性,我非常感谢您的建议。再次感谢你!!!
答案 0 :(得分:0)
您可以在name
和city
上执行全文索引,并在查询中使用MATCH AGAINST,但这有点过分。