检查Oracle中不带LIKE的字符串中的子字符串

o4tp2gmn  于 2023-04-20  发布在  Oracle
关注(0)|答案(6)|浏览(160)

如何在不使用LIKE的情况下在Oracle中检查字符串中的子字符串?假设我想从一个表中选择姓氏中有字母“z”的所有用户:

SELECT * FROM users WHERE last_name LIKE '%z%';

这样可以,但我不想使用LIKE。有没有其他函数可以使用?

q1qsirdb

q1qsirdb1#

我猜你问的原因是性能?有instr函数。但在幕后工作的方式可能差不多。
也许你可以看看full text search
作为最后的手段,你会看到缓存或预计算列/索引视图。

o7jaxewo

o7jaxewo2#

如果你只对'z'感兴趣,你可以创建一个基于函数的索引。

CREATE INDEX users_z_idx ON users (INSTR(last_name,'z'))

那么你的查询将使用WHERE INSTR(last_name,'z') > 0
使用这种方法,你必须为你可能想要搜索的每个字符创建一个单独的索引。我想如果这是你经常做的事情,那么为每个字母创建一个索引可能是值得的。
另外,请记住,如果您的数据的名称以标准方式大写(例如,“Zaxxon”),那么您的示例和我的示例都不会匹配以Z开始的名称。您可以通过在搜索表达式中包含LOWER来纠正这一点:INSTR(LOWER(last_name),'z')

yftpprvb

yftpprvb3#

您可以使用INSTR这样做:

SELECT * FROM users WHERE INSTR(LOWER(last_name), 'z') > 0;

如果子字符串不在字符串中,则INSTR返回零。
出于兴趣,你为什么不想用like呢?
编辑:我冒昧地让搜索大小写不敏感,这样你就不会错过Bob Zebidee了。

bksxznpy

bksxznpy4#

数据库针对常见的使用场景进行了大量优化(LIKE就是其中之一)。
如果你想停留在DB级别,你不会找到一种更快的搜索方法。

dfty9e19

dfty9e195#

请记住,只有当包含与 predicate 匹配的行的块数明显小于表中的块数时,才值得使用全表扫描以外的任何方法来查找这些值。这就是为什么Oracle在使用LIKE '%x%'(其中x是一个非常小的字符串)时,通常会拒绝使用索引来进行全表扫描的原因。例如,如果优化器认为使用索引仍然需要对(比如说)20%的表块进行单块读取,那么全表扫描可能比索引扫描更好。
有时候,你知道你的 predicate 比优化器估计的更有选择性,在这种情况下,你可以考虑提供一个优化器提示来对相关列执行索引快速全扫描(特别是当索引比表小得多的时候)。

SELECT /*+ index_ffs(users (users.last_name)) */
       * 
FROM   users
WHERE  last_name LIKE "%z%"
ghhkc1vu

ghhkc1vu6#

尝试使用函数REGEXP_INSTR

相关问题