2016-02-17 3 views
0

Скажите поле «Имя» в таблице 1 и «NameDetail» находится в таблице 2. Они оба являются индексами.Substr() удаляет использование индекса

Name NameDetail 
Jack JackJohnson 
Kent KentJacobs 

Я пытаюсь присоединиться к «Name» = «NameDetail». Но так как они не совсем то же самое. Я действительно пытаюсь присоединиться к «Name» = substr (NameDetail, 0,4); Предполагая, что он всегда будет первым 4 символами. Использование substr() удалит использование индекса, что значительно замедлит запрос.

Я пробовал использовать подстановочный знак, где «NameDetail» как «Name» || '%', но это не сработало. Что я здесь делаю неправильно? Кроме того, я являюсь пользователем базы данных. Не разработчик, поэтому я бы не смог создать новый индекс. Будьте очень благодарны, если кто-то может помочь. Благодаря!

+1

Какая таблица является драйвером - то есть, в какую сторону вы хотите присоединиться, и которая более избирательна? Что означает «не работает» для подстановочного подхода - вы на самом деле запустили то, что вы там написали, с строковым литералом '' Name '' или '' NameDetail ", как« Name »|| '%'' с идентификатор столбца? –

+0

Возможно, вы захотите создать [Function-Based Index] (https://oracle-base.com/articles/8i/function-based-indexes). Также имейте в виду, что индекс на основе функций [не может содержать значение «NULL») (https://docs.oracle.com/cd/E11882_01/appdev.112/e41502/adfns_indexes.htm#ADFNS00505). Тем не менее, вы можете использовать функцию 'NVL', чтобы ваш индекс всегда имел значение, отличное от' NULL'. – AndrewMcCoist

ответ

0

Я бы предложил создать индекс для выражения во второй таблице. Обратите внимание, что первый символ подстроки обозначается 0, а не 1. Так, для случая:

create index idx_table2_namedetail4 on table2(substr(NameDetail, 1, 4)); 

Oracle должен затем использовать индекс для этого соединения:

select . . . 
from table1 t1 join 
    table2 t2 
    on t1.name = substr(NameDetail, 1, 4); 
+0

Я бы не смог создать индекс, так как я всего лишь пользователь базы данных. – Futochan

0

Если вы приложили поле «Name» в кавычки для поиска по шаблону, как вы показали, то он не работает, потому что он будет искать строковый литерал «Имя», а не содержимое столбца «Имя». NameDetail LIKE Имя || «%» с другой стороны работы:

with nam as (select 'Jack' nam from dual union all select 'Kent' nam from dual) 
    ,namDet as (select 'JackJohnson' nameDetail from dual union all select 'KentJAcobs' nameDetail from dual) 
select n.nam, d.* 
from nam n 
    join namDet d 
on d.nameDetail like n.nam||'%'  

NAM NAMEDETAIL 
Jack JackJohnson 
Kent KentJAcobs 

К сожалению, это все равно будет, вероятно, имеют некоторые проблемы с производительностью более крупных наборов данных, поскольку нет никакого способа, чтобы сделать быстрый индексный к присоединиться для частичных совпадений.

Смежные вопросы