likes
comments
collection
share

MySQL模糊查询优化

作者站长头像
站长
· 阅读数 29

1. 准备

建表:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for actor
-- ----------------------------
DROP TABLE IF EXISTS `actor`;
CREATE TABLE `actor`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `idx_name`(`name`) USING BTREE # 对name建立索引
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of actor
-- ----------------------------

INSERT INTO `actor` VALUES (1, '郭德纲');
INSERT INTO `actor` VALUES (2, '于谦');
INSERT INTO `actor` VALUES (3, '高峰');
INSERT INTO `actor` VALUES (4, '侯振');
INSERT INTO `actor` VALUES (5, '栾云平');
INSERT INTO `actor` VALUES (6, '岳云鹏');
INSERT INTO `actor` VALUES (7, '朱云峰');
INSERT INTO `actor` VALUES (8, '孔云龙');
INSERT INTO `actor` VALUES (9, '张鹤伦');
INSERT INTO `actor` VALUES (10, '周九良');

SET FOREIGN_KEY_CHECKS = 1;

查看执行计划:

EXPLAIN SELECT id, name 
FROM actor
WHERE name LIKE '%云';

MySQL模糊查询优化

虽然使用了索引,但是从rows来看还是进行的全盘扫描,导致索引失效。 如果%在右边是什么情况呢?

MySQL模糊查询优化 并不会导致索引失效。针对%在前的模糊查询如何优化呢?大致有以下几种方法。

2.创建全文索引,比较耗费资源

3. 使用搜索引擎

4. 使用辅助列优化

思路:

  1. 创建一个虚拟列name_v作为name的映射,二者的字符串是逆序的

  2. 对name和name_v分别建立索引

  3. 在插入数据时,name正常插入,name_v插入的时name反转后的

  4. 在查询时

    a. 针对%abc,去name_v列中去模糊查询cba%

    b. 针对abc%,去name列中正常模糊查询abc%

    c. 最后把两个查询结果通过UNION合并起来,得到最终结果集

演示:

ALTER TABLE `actor` ADD COLUMN `name_v` VARCHAR(50) NOT NULL DEFAULT ''; # 创建辅助列
ALTER TABLE `actor` ADD INDEX `id_name_v`(`name_v`); # 创建索引
UPDATE `actor`
SET `name_v` = REVERSE(`name`); # 更新表数据
EXPLAIN SELECT id, name 
FROM actor
WHERE name_v LIKE '云%' # 相当于name LIKE '%云'
UNION
SELECT id, name 
FROM actor
WHERE name LIKE '云%';

MySQL模糊查询优化

总结

如果模糊查询的列字符个数比较多,或者总体记录数较多,建议使用搜索引擎来做。 如果模糊查询的列字符个数不多且总体记录数不多,建议使用虚拟列来做。

转载自:https://juejin.cn/post/7379569983129255951
评论
请登录