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

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

Вариант через instr, как-то сильно по практологически выглядит. IMHO
...
Рейтинг: 0 / 0
10.11.2020, 16:28
    #40016862
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в символьном столбце
Leonid Kudryavtsev
Вариант через instr, как-то сильно по практологически выглядит. IMHO
Напрасно. instr-у не мешают знания о метасимволах…
...
Рейтинг: 0 / 0
12.11.2020, 07:38
    #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
12.11.2020, 08:49
    #40017417
dmdmdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в символьном столбце
Свежеразбаненный неофит начинает делиться своими размышлениями.
Вместо прочтения документации по CBO, анализа планов.
Все внимаем.
...
Рейтинг: 0 / 0
12.11.2020, 17:14
    #40017614
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в символьном столбце
dmdmdm,

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

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

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

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

2

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

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

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

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


Да Да Да


.....
stax
...
Рейтинг: 0 / 0
12.11.2020, 17:53
    #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
12.11.2020, 18:15
    #40017659
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в символьном столбце
booby,

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Потом бенчмарк устроим.
...
Рейтинг: 0 / 0
12.11.2020, 20:11
    #40017699
SY
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
13.11.2020, 00:24
    #40017756
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Поиск в символьном столбце
SY,

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


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