Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Медленнее стал работать regexp_replace  [new]
GrandMaster
Member

Откуда:
Сообщений: 147
При переходе на новую версию Oracle 10.2.0.1.0 c 10.1.0.2.0 в 10 раз медленнее стал работать regexp_replace.
Думаю это связанно с настройками сервера. Кто-нибудь сталкивался с этим?
21 сен 06, 19:33    [3169897]     Ответить | Цитировать Сообщить модератору
 Re: Медленнее стал работать regexp_replace  [new]
GrandMaster
Member

Откуда:
Сообщений: 147
Вот конкретный пример:

declare
s string(100);
begin
for i in 1..10000
loop
s:=regexp_replace(to_char('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'||i),'(.*)(.)+F(.*)','\2',1,1,'i');
end loop;
end;


В Oracle 10.2.0.1.0 выполняеться - 14 сек, Oracle 10.1.0.2.0 - 1,4 сек. Проверял на разных серверах.
22 сен 06, 14:02    [3172904]     Ответить | Цитировать Сообщить модератору
 Re: Медленнее стал работать regexp_replace  [new]
GrandMaster
Member

Откуда:
Сообщений: 147
Сорри поправка:

declare
s string(100);
begin
for i in 1..10000
loop
s:=regexp_replace('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'||i,'(.*)(yandex)/([0-9\.]*)(.)+F\)(.*)','\2',1,1,'i');
end loop;
end;
22 сен 06, 14:05    [3172928]     Ответить | Цитировать Сообщить модератору
 Re: Медленнее стал работать regexp_replace  [new]
Feech
Member

Откуда:
Сообщений: 443
Такая же ситуация:
10.1.0.5: 00:00:01.06
10.2.0.2: 00:00:25.04

Железо одинаковое (по крайней мере, CPU и RAM, остальное, имхо, тут не важно).
22 сен 06, 14:19    [3173024]     Ответить | Цитировать Сообщить модератору
 Я это дело послал в Оракл  [new]
Sergei.Agalakov
Member

Откуда:
Сообщений: 575
Отныне это будет известно как баг 5581099.
Спасибо сообщившим.
4 окт 06, 23:39    [3222820]     Ответить | Цитировать Сообщить модератору
 Получил ответ из Металинка. Это не баг, а фича.  [new]
Sergei.Agalakov
Member

Откуда:
Сообщений: 575
Hi Sergei,
After some research we think we have found the cause of this issue.

The regular expression engine in 10gR2 exhaustively checks the permutations in which the pattern can be applied. When the pattern is not anchored at its left hand end, e.g. '.*' or similar as the leading part of the regular expression, there are many different locations where the pattern can start applying to the source data. Consequently, these unanchored expressions can take a long time to evaluate.

To improve the performance of the regular expression evaluation, it is best to ensure that the left hand end of the pattern has an anchor to the data.
For example, inserting '^' to anchor the pattern to the start of the source data. Also, in some cases, it may be that the '.*' is unnecessary and can be removed.

Looking at your testcase we had:

declare
s string(100);
begin
for i in 1..10000
loop
s:=regexp_replace('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT5.1)'
||i,'(.*)(yandex)/([0-9\.]*)(.)+F\)(.*)','\2',1,1,'i');
end loop;
end;
/

Which I've just run twice and got results of 00:00:29.39 and 00:00:29.12

Then I simply added ^ to the expression to get
||i,'^(.*)(yandex)/([0-9\.]*)(.)+F\)(.*)','\2',1,1,'i');
on line 7, and then it ran in 00:00:01.98 and 00:00:02.07 respectively.

In 10.1 the pattern change made no difference to the elapsed execution time, we currently think that this is due to a bug in 10.1 and it wrongly treats the regular expression as always being anchored at the start of the data, and that this behaviour has been corrected in 10.2, leading to the large differences in timing if you do not anchor the expression yourself.
4 дек 06, 21:41    [3489995]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить