Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / not regexp_like vs not like / 15 сообщений из 15, страница 1 из 1
15.06.2018, 15:12
    #39661329
JuliaTr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
сегодня попросила девелопера заменить 'not regexp_like' в запросе на обчный 'not like'.
Время выполнения упало с 4 минут до 20 секунд.

Делелопер расстроился и попросил разъяснений почему.
У меня ничего кроме как "regexp тяжелый, жрет CPU" в голову ничего не лезет.
А правда, почему?

Вот простой пример:
create table reg1 as select rownum id, object_id, object_name from dba_objects;
insert into reg1 select * from reg1;
insert into reg1 select * from reg1;
insert into reg1 select * from reg1;
commit;

Вариант 1:
select object_name,sum(id), sum(object_id) from reg1
where not regexp_like (object_name, 'AAA|BBB|CCC|DDD|EEE','i')
group by object_name;


Вариант 2:
select object_name,sum(id), sum(object_id) from reg1
where not (upper(object_name) like '%AAA%' or upper(object_name) like '%BBB%' or upper(object_name) like '%CCC%' or upper(object_name) like '%DDD%' or upper(object_name) like '%EEE%')
group by object_name;


первый бежит 52 сек, второй 3.
Если смотреть на trace, то перый ждет 50sec на CPU.


Если из первого варианта уберу часть условий - бежит быстрее.
типа: ...where not regexp_like (object_name, 'AAA','i')...

он чего, каждое условие отдельно пробегает?

Это что, глюк, фича?

12.2 если что.
...
Рейтинг: 0 / 0
15.06.2018, 15:45
    #39661349
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
JuliaTr,

можно еще с instr сравнить

.....
stax
...
Рейтинг: 0 / 0
15.06.2018, 16:14
    #39661376
JuliaTr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
StaxJuliaTr,

можно еще с instr сравнить

.....
stax

instr тоже шустрый. Но нам не подошел, т.е. надо было конец строки фиксированый иметь. Типа
where not regexp_like (object_name, '.*AAA$|.*BBB$|.*CCC$|.*DDD$|.*EEE$','i').


в примере просто по-максимуму упрощенно, но с той же особенностью.
...
Рейтинг: 0 / 0
15.06.2018, 16:18
    #39661378
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
JuliaTrт.е. надо было конец строки фиксированый иметь. Типа
where not regexp_like (object_name, '.*AAA$|.*BBB$|.*CCC$|.*DDD$|.*EEE$','i').
Код: plsql
1.
substr in
...
Рейтинг: 0 / 0
15.06.2018, 16:22
    #39661381
JuliaTr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
Вариантов много.
Интересно другое.
Почему REGEXP_LIKE так себя ведет?
Это баг?

Ну просто огромная разница, причем не описаная в документации.
...
Рейтинг: 0 / 0
15.06.2018, 16:29
    #39661384
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
JuliaTrПочему REGEXP_LIKE так себя ведет?
Это баг?Нет. RE тяжелы сами по себе.
...
Рейтинг: 0 / 0
16.06.2018, 01:49
    #39661495
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
ElicRE тяжелы сами по себе.
Причем задача ТС (N символов в конце строки) - как раз одна из тех, которые НЕ следует решать на RE.
...на самом деле этот пост я делаю ради вот этой ссылки (для особых ценителей): http://regex.info/blog/2006-09-15/247
...
Рейтинг: 0 / 0
16.06.2018, 10:09
    #39661519
JuliaTr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
Понятно.
Спасибо всем.

Логично, но вот поведение, когда AAA|BBB|CCC в 3 раза медленней чем просто AAA, от RE все равно не ожидалось.
Убираем нафиг.
Надо будет в понедельник потестировать что-то аналогичное тем же перлом с большим файлом, и сравнить время.
Даже интересно стало.
...
Рейтинг: 0 / 0
16.06.2018, 18:29
    #39661585
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
JuliaTr,

Код: perl
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.
[xtender@orasql ~]$ cat test.sh
#!/bin/bash

n=5000000

time (cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n $n | \
    perl -ne 'print if /AAA|BBB|CCC/;' \
    | wc -l)

time (cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n $n | \
    perl -ne 'print if index($_,"AAA")>=0 || index($_,"BBB")>=0 || index($_,"CCC")>=0;' \
    | wc -l)

[xtender@orasql ~]$ bash test.sh
1850

real    0m6.216s
user    0m12.650s
sys     0m5.739s

1896

real    0m7.301s
user    0m15.234s
sys     0m7.324s

тут регулярка быстрее чем 3 поочередных вызова функции
...
Рейтинг: 0 / 0
16.06.2018, 19:33
    #39661596
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
полуоффтоп: сделал сравнение perl/python на этом примитиве
python_re.py
Код: python
1.
2.
3.
4.
5.
6.
7.
8.
#!/usr/bin/python

import sys
import re

for line in sys.stdin:
    if re.search("AAA|BBB|CCC", line):
        print line

python_in.py
Код: python
1.
2.
3.
4.
5.
6.
7.
#!/usr/bin/python

import sys

for line in sys.stdin:
    if "AAA" in line or "BBB" in line or "CCC" in line:
        print line

test.sh
Код: perl
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.
#!/bin/bash

n=5000000

echo ================
echo Perl: re
time (cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n $n | \
    perl -ne 'print if /AAA|BBB|CCC/;' \
    | wc -l)

echo ================
echo Perl: instr
time (cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n $n | \
    perl -ne 'print if (index($_,"AAA")!=-1 || index($_,"BBB")!=-1 || index($_,"CCC")!=-1);' \
    | wc -l)

echo ================
echo Python: re
time (cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n $n | \
    ./python_re.py \
    | wc -l)

echo ================
echo Python: instr
time (cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n $n | \
    ./python_in.py \
    | wc -l)

echo ================
echo Egrep:
time (cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n $n | \
    grep -E '(AAA|BBB|CCC)' \
    | wc -l)


Результаты
Код: perl
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.
$ ./test.sh
================
Perl: re
1856

real    0m14.682s
user    0m30.402s
sys     0m13.661s
================
Perl: instr
1746

real    0m22.335s
user    0m45.546s
sys     0m20.691s
================
Python: re
3692

real    0m30.140s
user    1m11.815s
sys     0m21.737s
================
Python: instr
3828

real    0m25.165s
user    0m49.443s
sys     0m23.698s
================
Egrep:
1887

real    0m46.185s
user    1m7.946s
sys     0m35.156s

...
Рейтинг: 0 / 0
16.06.2018, 21:23
    #39661606
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
Тоже поучаствую.

Если в питоне сделать предварительную компиляцию выражения, то результаты становятся сравнимыми с перлом:

python_re-c.py
Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
#!/usr/bin/python

import sys
import re

regex = re.compile("AAA|BBB|CCC")

for line in sys.stdin:
    if regex.search(line)!=None:
        print line



Результат см. re-c
Код: 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.
================
Python: re
3736

real	0m8,816s
user	0m13,045s
sys	0m4,550s
================
Python: re-c
3666

real	0m5,221s
user	0m9,510s
sys	0m4,400s
================
Python: instr
3810

real	0m5,976s
user	0m7,572s
sys	0m5,283s
================
Perl: re
1824

real	0m5,977s
user	0m9,200s
sys	0m5,002s
================
Egrep:
1821

real	0m5,782s
user	0m6,043s
sys	0m5,136s

...
Рейтинг: 0 / 0
16.06.2018, 23:58
    #39661627
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
Alexander A. Sak,

а какая версия питона? у меня на 2.7.5 магии не вышло:
Код: python
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.
# python --version
Python 2.7.5

# cat python_re.py
#!/usr/bin/python

import sys
import re

regex = re.compile("AAA|BBB|CCC")

for line in sys.stdin:
    if regex.search(line)!=None:
        print line
# cat test.sh
#!/bin/bash

n=5000000
w=32

echo ================
echo Perl: re
time (cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $w | head -n $n | \
    perl -ne 'print if /AAA|BBB|CCC/;' \
    | wc -l)

echo ================
echo Python: re
time (cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $w | head -n $n | \
    ./python_re.py \
    | wc -l)

echo ================
echo Egrep:
time (cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $w | head -n $n | \
    grep -E '(AAA|BBB|CCC)' \
    | wc -l)
# ./test.sh
================
Perl: re
1909

real    0m6.038s
user    0m13.228s
sys     0m6.045s
================
Python: re
3730

real    0m9.517s
user    0m21.021s
sys     0m8.028s
================
Egrep:
1796

real    0m11.224s
user    0m18.561s
sys     0m10.206s

...
Рейтинг: 0 / 0
17.06.2018, 00:11
    #39661628
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
чуток изменил тест-кейс, чтобы данные сто раз не генерить
python_re.py
Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
#!/usr/bin/python

import sys
import re

regex = re.compile("AAA|BBB|CCC")

for line in sys.stdin:
    if regex.search(line)!=None:
        print line

test.sh
Код: perl
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.
#!/bin/bash

n=5000000
w=32
fname=./test_data

if [ ! -f ./test_data ]; then
   cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $w | head -n $n > $fname
fi

echo ================
echo Perl: re
time (cat $fname | \
    perl -ne 'print if /AAA|BBB|CCC/;' \
    | wc -l)

echo ================
echo Python: re
time (cat $fname | \
    ./python_re.py \
    | wc -l)

echo ================
echo Egrep:
time (cat $fname | \
    grep -E '(AAA|BBB|CCC)' \
    | wc -l)


типичный результат повторного вызова
Код: bash
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
$ ./test.sh
================
Perl: re
1786

real    0m1.738s
user    0m1.681s
sys     0m0.168s
================
Python: re
3572

real    0m2.849s
user    0m2.800s
sys     0m0.156s
================
Egrep:
1786

real    0m0.373s
user    0m0.341s
sys     0m0.097s


ps. Оказывается у тега SRC нет варианта для bash/sh, но есть для perl
...
Рейтинг: 0 / 0
17.06.2018, 19:53
    #39661726
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
xtenderAlexander A. Sak,
а какая версия питона? у меня на 2.7.5 магии не вышло:


Python 2.7.15rc1 на Убунте 18.04.
...
Рейтинг: 0 / 0
18.06.2018, 10:03
    #39661836
JuliaTr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
not regexp_like vs not like
у меня на питоне тоже медленнее.
Python 2.6.6

и из примера видно, как только добавляетя 'OR', то сразу в два раза медленнее бежит.
А там уже не важно сколько условий добававлено.


Perl: re (looking for AAA|BBB|CCC|DDD):
2511

real 0m2.742s
user 0m2.538s
sys 0m0.191s
================
Perl: re (looking for AAA|BBB):
1267

real 0m2.506s
user 0m2.326s
sys 0m0.173s
================
Perl: re (looking for AAA):
622

real 0m1.216s
user 0m1.084s
sys 0m0.131s
================
Python: re (looking for AAA|BBB|CCC|DDD):
5022

real 0m4.597s
user 0m4.453s
sys 0m0.133s
================
Python: re (looking for AAA|BBB):
2534

real 0m4.128s
user 0m3.964s
sys 0m0.132s
================
Python: re (looking for AAA):
1244

real 0m2.098s
user 0m1.985s
sys 0m0.110s
================
Egrep (looking for AAA|BBB|CCC|DDD):
2511

real 0m0.527s
user 0m0.448s
sys 0m0.074s
================
Egrep (looking for AAA|BBB):
1267

real 0m0.514s
user 0m0.440s
sys 0m0.071s
================
Egrep (looking for AAA):
622

real 0m0.201s
user 0m0.119s
sys 0m0.080s

...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / not regexp_like vs not like / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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