介绍
在数据库中,模糊查询是一种常用的搜索方式。它可以匹配部分指定的关键字来搜索更多的结果。在一些情况下,需要查找类似的数据,但由于数据过多 或 数据的字符格式限制,单一的查询无法满足需求。这时,就可以使用模糊查询。模糊查询是利用关键词模糊匹配的方式来查找相关数据。比如,模糊匹配姓,地址,文本内容等。
在MySQL里可以使用LIKE运算符来实现模糊查询。LIKE运算符可以配合通配符一起使用。通配符包括"%“和”_",其中%代表任意数量的字符,而_代表单个字符。
因为MySQL数据索引组织表特性,因此在查询条件中已索引查询性能最佳。但模糊查询有些情况,无法使用到索引。
场景示例
下面是Like语句使用示例。可以通过示例有效的使用模糊查询。
#表结构如下:
mysql> CREATE TABLE `employees` (
`emp_no` int NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` enum('M','F') NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`),
KEY `idx_lname` (`last_name`)
) ENGINE=InnoDB
1.在不使用通配符情况下,LIKE语句等于=一样的效果。
mysql>EXPLAIN SELECT * FROM employees where last_name like 'C' ;
2.通配符%结合使用的场景。从3种Like执行计划来看,只要前面没有%通配符,就可以使用索引。
mysql>EXPLAIN SELECT * FROM employees where last_name like '%C' ;
mysql>EXPLAIN SELECT * FROM employees where last_name like '%C%' ;
mysql>EXPLAIN SELECT * FROM employees where last_name like 'C%' ;
3.通配符_结合使用的场景。从3种Like执行计划来看,只要前面也没有使用_通配符,就可以使用索引。
mysql>EXPLAIN SELECT * FROM employees where last_name like '_C' ;
mysql>EXPLAIN SELECT * FROM employees where last_name like '_C_' ;
mysql>EXPLAIN SELECT * FROM employees where last_name like 'C_' ;
到此,可以总结出,在MySQL的Like查询语句中,通配符不在前面就可以使用索引。
4.返回SELECT列表里只有索引列和主键,不管是否前后使用通配符%,执行计划就使用索引。
返回SELECT列表里只有索引列和主键,不管是否使用通配符,执行计划就使用索引。
因为不需要全字段扫描,也不需要进行回表,执行计划就会选择索引数据,进行匹配。
mysql>EXPLAIN SELECT emp_no,last_name FROM employees where last_name like '%C%' ;
备注:对于二级索引来说,索引字段包含索引列和主键信息。所以执行计划选择使用索引列,进场扫描。
5.返回SELECT列表里只有索引列和主键,前后通配符区别:
下面通过Explain FORMAT=TREE,看下具体的输出信息。
mysql> EXPLAIN FORMAT=TREE SELECT emp_no,last_name FROM employees where last_name like '%C%' ;
+-------------------------------------------------------------------------------------------------+
| EXPLAIN | +-------------------------------------------------------------------------------------------------+
| -> Filter: (employees.last_name like '%C%') (cost=30889 rows=33286)
-> Index scan on employees using idx_lname (cost=30889 rows=299600) |
+-------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> EXPLAIN FORMAT=TREE SELECT emp_no,last_name FROM employees where last_name like 'C%' ;
+-------------------------------------------------------------------------------------------------+
| EXPLAIN | +-------------------------------------------------------------------------------------------------+
| -> Filter: (employees.last_name like 'C%') (cost=7587 rows=36412)
-> Covering index range scan on employees using idx_lname over ('C'