针对此种情形,有两种优化方法:
第一,可以把数据按照后缀做一个拆分,后缀部分单独为一个字段,然后给这个字段加一个索引。除了要加字段,此方法很完美~
建一个表 t3,把表 t2 的数据导进去。
CREATE TABLE `t3` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`r1` varchar(300) DEFAULT NULL,
`suffix_r1` varchar(6) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_suffix_r1` (`suffix_r1`)
) ENGINE=InnoDB
<localhost|mysql>insert into t3 select id,r1,right(r1,6) from t2;
Query OK, 24576 rows affected (19.05 sec)
Records: 24576 Duplicates: 0 Warnings: 0
再次执行 SQL 7,查询瞬间出来结果。
<localhost|mysql>select count(*) from t3 where suffix_r1 = 'sample';
+----------+
| count(*) |
+----------+
| 4 |
+----------+
1 row in set (0.00 sec)
第二,可以把数据反转过来后建立前缀索引查询记录。对表 t2 克隆一张表 t4。
<localhost|mysql>insert into t4 select id,reverse(r1) from t2;
Query OK, 24576 rows affected (5.25 sec)
Records: 24576 Duplicates: 0 Warnings: 0
查询关键词进行反转查询,
<localhost|mysql>select count(*) from t4 where r1 like 'elpmas%';
+----------+
| count(*) |
+----------+
| 4 |
+----------+
1 row in set (0.00 sec)
再看下查询计划,走了前缀索引。不过这样的缺点是查询记录的时候需要在 SQL 层处理记录数据,加上反转函数。
<localhost|mysql>explain select count(*) from t4 where r1 like 'elpmas%'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t4
partitions: NULL
type: range
possible_keys: idx_r1_p
key: idx_r1_p
key_len: 27
ref: NULL
rows: 4
filtered: 100.00
Extra: Using where; Using index
1 row in set, 1 warning (0.00 sec)