wb.ouyang

毕竟几人真得鹿,不知终日梦为鱼

导航

案例:前缀匹配和后缀匹配,根据【手机号135****6764】,或根据【用户名首字符和手机尾号】,使用【计算列+前缀索引】

 表数据tb_person,参考测试java程序插入单表2000万条数据(MySQL,PostgreSQL,达梦)

1、场景一:根据手机号135****6764搜索

方式一:没有索引select *,查询时间 13s

select * from tb_person where tel like '135%' and tel like '%6764';

 

方式二:

没有索引,查询耗时 4.3s

select id from tb_person where tel like '135%' and tel like '%6764';

没有索引,关联查询,查询耗时 4.6s

select p.* from tb_person p join(
select id from tb_person where tel like '135%' and tel like '%6764'
) a on a.id=p.id;

image

没有索引,子查询,查询耗时 4.6s

select p.* from tb_person p where id in(
select id from tb_person where tel like '135%' and tel like '%6764'
);

 

方式三:

给 tel 字段创建索引

CREATE INDEX idx_tel ON tb_person(tel);

使用索引 idx_tel,关联查询,查询耗时 0.4s

select p.* from tb_person p join(
select id from tb_person where tel like '135%' and tel like '%6764'
) a on a.id=p.id;

image

 

方式四:计算列+前缀索引

-- 添加计算列 tel_lastfour
ALTER TABLE tb_person
ADD column tel_lastfour CHAR(4) GENERATED ALWAYS AS (RIGHT(tel, 4)) VIRTUAL;
-- 建立前缀索引,tel(3)取tel字段前3个字符
CREATE INDEX idx_tel_lastfour ON tb_person(tel(3),tel_lastfour);

查询耗时 0.01s

select p.* from tb_person p join(
select id from tb_person where tel like '135%' and tel_lastfour = '6764'
) a on a.id=p.id;

 

2、场景二:根据【用户名首字符和手机尾号】搜索

方式一:在字段 name,tel 上建立复合索引

根据【用户名首字符和手机尾号】搜索,比如 李*,****6764

-- 建立前缀索引,name(1)取name字段前1个字符
CREATE INDEX idx_name_tel ON tb_person(name(1),tel);

查询耗时 5.2s

select p.* from tb_person p join(
select id from tb_person where name like '李%' and tel like '%6764'
) a on a.id=p.id;

 

方式二:计算列+前缀索引

-- 添加计算列 tel_lastfour
ALTER TABLE tb_person
ADD column tel_lastfour CHAR(4) GENERATED ALWAYS AS (RIGHT(tel, 4)) VIRTUAL;
-- 建立前缀索引,name(1)取name字段前1个字符
CREATE INDEX idx_name_tellastfour ON tb_person(name(1),tel_lastfour);

查询耗时 0.01s

select p.* from tb_person p join(
select id from tb_person where name like '李%' and tel_lastfour = '6764'
) a on a.id=p.id;

 

posted on 2025-12-20 19:51  wenbin_ouyang  阅读(28)  评论(0)    收藏  举报