powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Поиск в символьном столбце
21 сообщений из 21, страница 1 из 1
Поиск в символьном столбце
    #40016835
Фотография Pastic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А кто-нибудь проверял, что быстрее работает:
1) upper(x.name) like '%'||upper(i_name)||'%' или
2) instr(upper(x.name), upper(i_name))>0?
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40016843
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не проверял, но думаю что первое:

1) есть надежда, что '%'||upper(i_name)||'%' будет вычисляться всегда один раз
2) можно построить function index по выражению upper(x.name)
что-то еще

Вариант через instr, как-то сильно по практологически выглядит. IMHO
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40016862
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
Вариант через instr, как-то сильно по практологически выглядит. IMHO
Напрасно. instr-у не мешают знания о метасимволах…
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017408
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Pastic
А кто-нибудь проверял, что быстрее работает:
1) upper(x.name) like '%'||upper(i_name)||'%' или
2) instr(upper(x.name), upper(i_name))>0?


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

Если спецсимволов в i_name не ожидается, есть ещё regexp_like(x_name,i_name,'i'). Если ожидаются, то (1) и (2) могут не совпадать по смыслу.
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017417
dmdmdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Свежеразбаненный неофит начинает делиться своими размышлениями.
Вместо прочтения документации по CBO, анализа планов.
Все внимаем.
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017614
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dmdmdm,

"Я думаю, значит существую".

Я высказал мнение на вопрос ТС на основании своего скромного опыта SQL, и достаточного опыта работы с оптимизаторами.

Вы сказали что ответ есть в документации, и в "планах", но что-то не даёт вам ответить на вопрос ТС?

Вопрос то простой - что быстрее - (1) или (2). Экспертам должно быть по плечу.
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017625
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

2

.....
stax
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017628
K790
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

НеофитSQLдостаточного опыта работы с оптимизаторами
так поделитесь результатами работы оптимизатора, в первом и втором случае.
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017630
K790
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

так прямо однозначно? :)
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017641
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
K790
Stax,

так прямо однозначно? :)


Да Да Да


.....
stax
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017650
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
K790
Stax,

так прямо однозначно? :)

однозначно то, что второй вариант предотвратит "неумышленное" использование оптимизатором индекса по upper(x.name),
даже если он кем-то будет создан со специальной целью нанесения вреда запросу, в фильтре которого присутствует upper(x.name).

Для конкретной использованной формы instr(upper(x.name), upper(i_name)) это безусловное благо,
по сравнению с услиями, которые нужно буждет предпринять в случае like '%'||upper(i_name)||'%' , чтобы избежать совсем такого индекса, или хотя бы превратить его использование в index fast full scan.

upd;
я не хочу сказать, что такой индекс универсально плохой.
Я говорю, что в первом случае, его использование нежелательно, и за это, может быть, придётся побороться...
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017659
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
booby,

разве в случае с % в начале есть шанс, что используется индекс?
Индекс помог бы если бы сравнение происходило с начала строки, но тогда споткнется об upper()
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017661
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby,

Не торопись делать выводы насчет индекса на UPPER(X.NAME) ничего не зная о ширине таблицы и кардинальности выборки. Вполне возможно FULL INDEX SCAN на UPPER(X.NAME) улучшит производительность. Хотя на "что быстрее" он не повлияет ибо как LIKE так и INSTR могут им воспользоваться.

SY.
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017664
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
...
2) можно построить function index по выражению upper(x.name)
что-то еще
...

такой индекс может быть использован.
тогда со 100% вероятностью получится index full scan, а за fast full scan нужно устраивать операцию
по принуждению к использованию такой стратегии.
В данном случае предпочтительнее "что-то еще"...
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017671
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
K790
НеофитSQL,

НеофитSQLдостаточного опыта работы с оптимизаторами

так поделитесь результатами работы оптимизатора, в первом и втором случае.

Мое мнение, новичка:
Если цель - обработать каждую из этих строк (а не, скажем, использовать в подзапросе exists), то Оракл оптимизатор отдыхает, т.к. поиск ведется в середине строки, без указания что слово поиска ограничено пробелами или другими разделителями. Т.е. ни один индекс, обычный или фулл-текст в общем случае не поможет, имеем full scan, единственная оптимизация скана - длина поискового слова, можно не смотреть на строчки которые короче.

Вопросы оптимизации UPPER() решаются одинаково в обоих случаях.
Смена контекста не происходит в обоих случаях.

План, думаю, будет одинаковый.

Конструкция (2) переводится в наиболее эффективную машинную операцию (согласно моим знаниям 86 ассемблера)
Значит, конструкция 1 в лучшем случае будет равна (2).

Для этого, оптимизатор должен заметить одиночные '%' с обеих сторон, и вместо манипуляций с памятью, слияния строк, интерпретации спец символов '%' и умных проверок применить конструкцию (2) сразу. Для этого случай одиночных '%'||xxx||'%' должен быть конкретно записан в правилах оптимизатора.

А теперь нужно попробовать и померять, желательно на разных версиях оракла.
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017672
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

Вы правы, все черти всегда в деталях.

я предполагах "почти везде заполненность" для i_name, "большую таблицу" и не слишком малую ширину для i_name,

кажется, что безуловная полезность такого индекса, наверно, проявится на очень широких таблицах,
например, когда общая ширина строки в таблице в 64 или 128 раз больше ширины i_name.

про умения instr - не знал.
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017680
K790
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

авторМое мнение...
Здесь привыкли верить приведенным тестам и цифрам. Поиск по трассировкам по форуму вам в помощь.
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017683
K790
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а также ответ
22230561
самый правильный, имхо
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017695
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я вижу два твердых голоса в пользу преимущества (2), пока ни одного - в пользу (1).

Будьте смелее, товарищи теоретики и практики. Блесните своими знаниями и опытом и потенцией в простом вопросе.
Не бойтесь ошибиться, это не экзамен.

Потом бенчмарк устроим.
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017699
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby

про умения instr - не знал.


Это не про INSTR. Oracle находит ф-цию которой на вход подается индексированное выражение. Oracle не знает логику ф-ции посему считает NULLы нужно тоже передавать. Это значит индекс будет использоваться только если Oracle знает что индекс содержит все строки. Тогда можно читать индекс а не таблицу для подачи ф-ции:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
QL> create or replace
  2  function f1(p_param number)
  3  return number
  4  is
  5  begin
  6  return p_param;
  7  end;
  8  /

Function created.

SQL> explain plan for select empno from emp where f1(empno) = 0;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------
Plan hash value: 179099197

---------------------------------------------------------------------------
| Id  | Operation        | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT |        |     1 |     4 |     1   (0)| 00:00:01 |
|*  1 |  INDEX FULL SCAN | PK_EMP |     1 |     4 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
SQL> create table emp2 as select * from emp;

Table created.

SQL> create index emp2_fbi on emp2(upper(ename),0); -- ename is NULLable

Index created.

SQL> explain plan for select upper(ename) from emp2 where instr(upper(ename),'X') > 0;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------
Plan hash value: 2209192357

-----------------------------------------------------------------------------
| Id  | Operation        | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT |          |     1 |     7 |     1   (0)| 00:00:01 |
|*  1 |  INDEX FULL SCAN | EMP2_FBI |     1 |     7 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------

   1 - filter(INSTR(UPPER("ENAME"),'X')>0)

13 rows selected.

SQL> explain plan for select upper(ename) from emp2 where rtrim(upper(ename),'X') is not null;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2209192357

-----------------------------------------------------------------------------
| Id  | Operation        | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT |          |     1 |     7 |     1   (0)| 00:00:01 |
|*  1 |  INDEX FULL SCAN | EMP2_FBI |     1 |     7 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------

   1 - filter(RTRIM(UPPER("ENAME"),'X') IS NOT NULL)

13 rows selected.

SQL>



SY.
...
Рейтинг: 0 / 0
Поиск в символьном столбце
    #40017756
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

Ok, get it. thanks.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Поиск в символьном столбце
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]