如何最好地索引此连接查询

时间:2014-12-05 14:20:05

标签: mysql

场景:我有一个表单,使用对后端的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中,它显示正在使用的其他索引。手指交叉。 谢谢给大家的帮助,我真的很感激,如果我能给你积分,我会这样做。

如果还有其他任何方法可以提高此查询的速度或安全性,我非常感谢您的建议。再次感谢你!!!

1 个答案:

答案 0 :(得分:0)

您可以在namecity上执行全文索引,并在查询中使用MATCH AGAINST,但这有点过分。