注册
模糊查询 LIKE、REGEXP_LIKE和INSTR 的正确打开方式
专栏/金的探索记录/ 文章详情 /

模糊查询 LIKE、REGEXP_LIKE和INSTR 的正确打开方式

2020/12/16 3335 3 0
摘要 本文通过不同需求下三种模糊查询的性能对比,比较出三种模糊查询在不同场景下的优势。

很多时候我们都需要用到模糊查询,但是在什么场景用什么查询方式才是最适合的呢?

下面通过几个简单的例子来比较一下常用的模糊查询。

首先准备两张表

CREATE TABLE TEST1 AS SELECT * FROM SYSOBJECTS; CREATE TABLE TEST2 AS SELECT * FROM DBA_TABLES WHERE OWNER = 'USER1';

ROUND1:列对列全表扫描

LIKE

SELECT * FROM TEST1 T1,TEST2 T2 WHERE T1.NAME LIKE '%'||T2.TABLE_NAME||'%' ;

执行耗时:563毫秒 1875行

INSTR

SELECT * FROM TEST1 T1,TEST2 T2 WHERE INSTR(T1.NAME,T2.TABLE_NAME)>0;

执行耗时:338毫秒 1875行

REGEXP_LIKE

SELECT * FROM TEST1 T1,TEST2 T2 WHERE REGEXP_LIKE(T1.NAME,T2.TABLE_NAME);

执行耗时:10.740秒 1875行

小结:在进行列列比较时,虽然同是全表扫描,但是 LIKE 和 INSTR 均可以利用批量处理来进行对比,因此性能明显优于 REGEXP_LIKE 函数。

ROUND2:列对值全表扫描

LIKE

SELECT * FROM TEST1 T1 WHERE T1.NAME LIKE '%A%';

执行耗时:16毫秒 1944行

INSTR

SELECT * FROM TEST1 T1 WHERE INSTR(T1.NAME,'A')>0

执行耗时:16毫秒 1944行

REGEXP_LIKE

SELECT * FROM TEST1 T1,TEST2 T2 WHERE REGEXP_LIKE(T1.NAME,'A');

执行耗时:21毫秒 1944行

小结:在进行列值比较时,LIKE、INSTR、REGEXP_LIKE 均可以利用批量处理来进行数据对比,但是多次执行后 REGEXP_LIKE 函数的性能稍差。

ROUND3:功能对比

添加测试数据和索引

INSERT INTO TEST1(NAME) VALUES ('113456'); INSERT INTO TEST1(NAME) VALUES ('123456'); INSERT INTO TEST1(NAME) VALUES ('133456'); INSERT INTO TEST1(NAME) VALUES ('143456'); INSERT INTO TEST1(NAME) VALUES ('1abc56'); COMMIT; CREATE INDEX IND_TEST1_NAME ON TEST1(NAME);

在前两轮的 PK 中,REGEXP_LIKE 表现差强人意,但是 REGEXP_LIKE 函数强大的功能,让我们在有些场景下不得不选择它来进行模糊查询。

例 1:查询出 TEST1 表中 name 列以1开头并以 56 结尾的数据。

REGEXP_LIKE

SELECT * FROM TEST1 T1 WHERE REGEXP_LIKE(T1.NAME,'1...56')

11111.png

能查询但是无法利用索引。

LIKE

SELECT * FROM TEST1 T1 WHERE T1.NAME LIKE '1___56'

22222.png

能查询并利用了索引,在大量数据情况下,利用索引的 LIKE 会占据很大的优势。

INSTR

无法满足条件

例 2:如果需要查到全部都是数字的列

REGEXP_LIKE

333333.png

LIKE 和 INSTR 却无能为力了。

不仅如此,使用 REGEXP_LIKE 还可以通过字符集、是否区分大小写、空格等一系列过滤条件来进行条件更严格的模糊查询。

综上所述:

  • 在无法利用索引的情况下,使用 INSTR 是最佳的选择;
  • 能利用索引的,只有 LIKE;
  • 如果条件很苛刻不好过滤判断,那么 REGEXP_LIKE 就派上用场了。
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服