为什么我的 mysql 模糊查询没有使用索引

1.案例

1.1 初始化测试数据

测试数据有两张简化的表,一个是商品类目表 goods_category,一个是商品表。两张表关系是类目与商品是一对多的关系,即一个类目可以对应多个商品。初始化脚本如下(testdb.sql)

#创建商品表
drop table goods;
CREATE TABLE `goods` (
  `goods_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '商品id',
  `goods_name` varchar(128) NOT NULL DEFAULT '' COMMENT '商品名称',
  `category_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '类目id',
  PRIMARY KEY (`goods_id`),
  KEY idx_category_id (`category_id`),
  KEY idx_goods_name (`goods_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';

#创建类目表
drop table goods_category;
CREATE TABLE `goods_category` (
    `category_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '商品类目id',
    `category_name` varchar(128) NOT NULL DEFAULT '' COMMENT '商品类目名',
    PRIMARY KEY (`category_id`),
    KEY idx_category_name (`category_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品类目表';

#插入测试数据
INSERT INTO `goods` (`goods_id`, `goods_name`, `category_id`) VALUES
(1, '女鞋1', 1),
(2, '女鞋2', 1),

(2, '女鞋2', 1),
(3, '女鞋3', 1),
(4, '男T恤1', 2),
(5, '男T恤2', 2),
(6, '女_包1', 3),
(7, '女_包2', 3),
(8, '女_包3', 3),
(9, '女_包4', 3),
(10, '女_包5', 3),
(11, '女_包6', 3);

INSERT INTO `goods_category` (`category_id`, `category_name`) VALUES
(2, 'T恤'),
(3, '箱包'),
(1, '鞋');
DELIMITER $$

DROP PROCEDURE IF EXISTS proc_initData$$

CREATE PROCEDURE proc_initData()
BEGIN
    DECLARE i INT DEFAULT 1;
    WHILE i<=10000 DO
        INSERT INTO test.goods (`goods_id`, `goods_name`, `category_id`) VALUES(i+100, CONCAT('女_包', i+100), 3);
        SET i = i+1;
    END WHILE;
END$$

DELIMITER ;
CALL proc_initData();

1.2 模糊查询条件左侧以通配符开头不能应用索引

我们知道对于模糊查询,通配符放在左侧是用不上索引的,这个很好理解,因为每条记录都是有可能匹配的,只有检查每条记录才能确定是不是满足模糊匹配条件,例如:

mysql> explain select * from goods where goods_name like '%T恤1';
+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | goods | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10122 |    11.11 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+

1.3 模糊查询条件以通配符结尾可以应用索引

MySQL 文档指出以通配符结尾的话,是可以应用上索引的,例如:

mysql> explain select * from goods where goods_name like '男T恤%';
+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys  | key            | key_len | ref  | rows | filtered | Extra
        |
+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | goods | NULL       | range | idx_goods_name | idx_goods_name | 514     | NULL |    2 |   100.00 | Using index condition |
+----+-------------+-------+------------+-------+--------------
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL模糊查询索引的原因有几个可能的情况: 1. 模糊查询使用通配符开头:如果模糊查询的字符串以通配符开头(如 %abc),MySQL无法使用索引进行优化,因为通配符开头的模糊查询无法利用B-tree索引的前缀匹配特性。 2. 模糊查询字符串太短:如果模糊查询的字符串长度过短(比如只有几个字符),那么MySQL可能会认为全表扫描比使用索引更高效,因为索引的开销可能会超过全表扫描。 3. 字符集问题:如果模糊查询的字段使用了某些特殊字符集(比如UTF8),MySQL可能无法使用索引进行匹配,因为字符集的不同会导致索引无法正确匹配查询条件。 解决这些问题的方法有几种: 1. 使用索引前缀:如果模糊查询的字符串不以通配符开头,可以尝试创建一个前缀索引,只包含字符串的前几个字符,以便利用索引的前缀匹配特性。 2. 使用全文索引MySQL提供了全文索引(Full-Text Index),可以用于处理模糊查询。全文索引可以更好地处理包含通配符的模糊查询。 3. 优化查询语句:可以对查询语句进行优化,如尽量避免在模糊查询使用通配符开头的字符串,或者使用更长的匹配字符串,以提高索引的利用率。 需要注意的是,优化模糊查询的方法可能因具体情况而异,需要根据实际场景进行测试和调整。可以使用MySQL的explain语句来查看查询执行计划,以确定是否使用索引

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值