interMedia Text using query

 
0
 
Oracle
ava
Sleepy_PIP | 05.02.2005, 19:44
ORA 9.2
Имеется простая табличка:

CREATE TABLE site_dir
(iddir NUMBER(20,0),
idsite NUMBER(*,0),
parent_iddir NUMBER(20,0),
dir_flg NUMBER(*,0),
fdir_name VARCHAR2(4000),
pdir_name VARCHAR2(250))
PCTFREE 10
INITRANS 1
MAXTRANS 255
TABLESPACE pip
STORAGE (
INITIAL 409600
MINEXTENTS 1
MAXEXTENTS 2147483645
)
/


в которой поле fdir_name содержит полное имя каталога FTP серверов (т.е. от корня '/' до пследнего каталога... т.е. например '/subruut/dir1/dir2/last_dir').
есть некий набор запросов (прямых, и через view) с условием на это поле like('/%...%')
Статистика сброшена.
План - по RULE. вполне удовлетворяющий план.
Теперь пытаюсь навесить на это поле CTXSYS.CONTEXT тип индекса как:

create index site_dir_ctx on site_dir(fdir_name) indextype is CTXSYS.CONTEXT;


после создания этого индекса все планы съезжают на COST оптимизацию, совсем мне не нужную.
full scan по site_dir появляется, и время выполнения запросов резко возрастает.
Сбрасываю этот индекс - все возвращяется в норму.
Сколько не читал про CTXSYS.CONTEXT - везде пишут что это типа здорово и как раз приминимо для оптимизации текстового поиска. Но практика показывает другое.
В чем я не прав? Почему наблюдается только ухудшение?
Спасибо!
Comments (20)
ava
igon | 06.02.2005, 01:24 #
Возможно, не совсем уместно для анализа достаточно коротких строк (даже если твои пути могут быть длиной до 4000 символов, что само по себе удивительно smile) использовать Oracle Text.
Если же в fdir_name хранятся URL и предполагается анализировать не компоненты пути, а содержимое файла, на который указывает URL, то
Цитата
use the URL_DATASTORE preference type during indexing.

Кроме того, для context индексов в запросах применяется CONTAINS, но не like.
Что-то я вообще не представляю совместную эффективность like и индексированного поля. И как тебе удается избежать full scan при наличии в запросе like('/%...%'), даже без индекса.
ava
Sleepy_PIP | 06.02.2005, 11:35 #
Цитата (igon @ 6.2.2005, 01:24)
Возможно, не совсем уместно для анализа достаточно коротких строк (даже если твои пути могут быть длиной до 4000 символов, что само по себе удивительно smile) использовать Oracle Text.

Если же в fdir_name хранятся URL и предполагается анализировать не компоненты пути, а содержимое файла, на который указывает URL, то

Цитата
use the URL_DATASTORE preference type during indexing.


Кроме того, для context индексов в запросах применяется CONTAINS, но не like.

Что-то я вообще не представляю совместную эффективность like и индексированного поля. И как тебе удается избежать full scan при наличии в запросе like('/%...%'), даже без индекса.

ну во первых like('/%...') - идет поиск все-ж по индесксу, т.к. 1-й символ предопределен.
Можно спорить что при этом эффективнее - обход всего дерева, или full scan по данным.
Но пока индекс эффективнее по практическим замерениям.
а во вторых - я не понимаю сути CTXSYS.CONTEXT индекса.
Он что - бъет строку на слова? (слов-то у меня и нет - просто длинная сторка).
В третьих - почему при исползовании CONTEXT план съезжает на cost и никакие хинты на него не действуют?

Т.е. для меня пока так и остается на понятным - когда CONTEXT эффективен? для каких типов данных и запросов он эффективен?

PS: хранятся у меня там строки вида: '/subruut/dir1/dir2/.../last_dir' ... вот в таком духе.

ava
igon | 06.02.2005, 17:10 #
Цитата
ну во первых like('/%...') - идет поиск все-ж по индесксу, т.к. 1-й символ предопределен

Предопределенность 1-го символа вряд ли имеет значение - like('/%dir2%') должен будет найти подстроку, которая может находиться в ЛЮБОЙ позиции исходной строки, начинающейся с '/'. Какая же здесь польза от индексирования?
ИМХО, CTXSYS.CONTEXT к замедлению может и не иметь отношения: попробуй создать обыкновенный индекс на поле и посмотреть, что будет с планом для запроса с like.

Цитата
Но пока индекс эффективнее по практическим замерениям
ИМХО, противоречит твоему утверждению
Цитата
после создания этого индекса ... full scan по site_dir появляется, и время выполнения запросов резко возрастает. Сбрасываю этот индекс - все возвращяется в норму.


Цитата
я не понимаю сути CTXSYS.CONTEXT индекса

О существовании Oracle Text я узнал благодаря твоему вопросу smile. После беглого просмотра создалось впечатление, что этот прибамбас предназначен для оптимизации обработки БОЛЬШИХ и многих текстовых документов, вплоть до MS Word, что, как я уже упоминал, явно не твой случай.

Может быть, стоит переосмыслить подход? В первую очередь постараться избавиться от like - фактически очень трудоемкой операции, применение которой допустимо, только если уже ничто другое придумать не удается. Мне сложно судить о твоей задаче (именно, что может находиться между %% и "однообразие" структуры путей), но возможный вариант - создание а ля dictionary для стандартных компонентов путей и поиск в них, но уже не через 'like', а '='.

Select * From site_dir
Where fdir_name in (select distinct fullURL from dictionary
where partURL = nvl('/dir1', partURL) or -- and
partURL = nvl('/dir2', partURL) or -- and
partURL = nvl('/dir3', partURL)
)

Можно даже создать словарь для ВСЕХ возможных строк поиска, тогда в подзапросе достаточно будет одного равенства :)

ava
guest | 06.02.2005, 19:26 #
Цитата (igon @ 6.2.2005, 17:10)
Цитата
ну во первых like('/%...') - идет поиск все-ж по индесксу, т.к. 1-й символ предопределен


Предопределенность 1-го символа вряд ли имеет значение - like('/%dir2%') должен будет найти подстроку, которая может находиться в ЛЮБОЙ позиции исходной строки, начинающейся с '/'. Какая же здесь польза от индексирования?

ИМХО, CTXSYS.CONTEXT к замедлению может и не иметь отношения: попробуй создать обыкновенный индекс на поле и посмотреть, что будет с планом для запроса с like.



Цитата
Но пока индекс эффективнее по практическим замерениям
ИМХО, противоречит твоему утверждению

Цитата
после создания этого индекса ... full scan по site_dir появляется, и время выполнения запросов резко возрастает. Сбрасываю этот индекс - все возвращяется в норму.




Цитата
я не понимаю сути CTXSYS.CONTEXT индекса


О существовании Oracle Text я узнал благодаря твоему вопросу smile. После беглого просмотра создалось впечатление, что этот прибамбас предназначен для оптимизации обработки БОЛЬШИХ и многих текстовых документов, вплоть до MS Word, что, как я уже упоминал, явно не твой случай.



Может быть, стоит переосмыслить подход? В первую очередь постараться избавиться от like - фактически очень трудоемкой операции, применение которой допустимо, только если уже ничто другое придумать не удается. Мне сложно судить о твоей задаче (именно, что может находиться между %% и "однообразие" структуры путей), но возможный вариант - создание а ля dictionary для стандартных компонентов путей и поиск в них, но уже не через 'like', а '='.



Select * From site_dir

 Where fdir_name in (select distinct fullURL from dictionary

                                      where partURL = nvl('/dir1', partURL) or -- and

                                                 partURL = nvl('/dir2', partURL) or -- and

                                                 partURL = nvl('/dir3', partURL)

                                 )



Можно даже создать словарь для ВСЕХ возможных строк поиска, тогда в подзапросе достаточно будет одного равенства smile

like('%...') никогда не будет использовать никакой индекс.
like('/%...') - может использовать индекс, т.к. подстрока поиска имеет предопределенное _начало_.
На практике так и происходит.
Без like обойтися я не могу, хоть и дерево каталогов разумеется у меня есть в виде именно дерева.
Задача простая - FTP search по паттернам. паттрены - произвольные. поиск и в полных путях каталогов и в файлах.
Когда-ж все-ж эффективен CONTEXT? - когда строки имеют слова??? - т.е. бъются на слова пробелом - разделителем?
Я имею набор строк с и без пробелами. длинны - до 2000 символов.
Но так и не разобрался пока.
Последние пробы - использовал оператор contains, проедварительно построив нужный индекс.
Никакого ускорения аналогичных с like запросов не увидел. План кстати посмотреть в SQL Navigator-е с contains не получается. а план запросов с like сехал на cost и времы возросло в порядки.
Т.е. я опять не понимаю где CONTEXT будет эффективен??
Чем различается сторока текста в MS Word от полного пути каталогов? - я по сути разницы не вижу.
ava
igon | 06.02.2005, 23:47 #
Цитата
like('%...') никогда не будет использовать никакой индекс.

like('/%...') - может использовать индекс, т.к. подстрока поиска имеет предопределенное _начало_.
Ты имеешь в виду это?
Цитата
Pattern Matching on Indexed Columns

When you use LIKE to search an indexed column for a pattern, Oracle can use the index to improve the statement's performance if the leading character in the pattern is not "%" or "_". In this case, Oracle can scan the index by this leading character. If the first character in the pattern is "%" or "_", the index cannot improve the query's performance because Oracle cannot scan the index.

Но:
1. Oracle сканирует только часть индекса, именно ту, для которой строки начинаются с "предопределенного" символа. Игнорирование остальной части естественно даст выигрыш в производительности.
2. У тебя ВСЕ строки начинаются с '/', поэтому сканирование индекса будет полным, без выигрыша в производительности, хотя в плане подключение индекса будет видно.
3. Преимуществом индексирования является возможность разместить в индексе записи, удовлетворяющие условиям поиска, ПОСЛЕДОВАТЕЛЬНО, "компактно" - при выходе за пределы компактного "проживания" поиск можно прекратить. Однако я не вижу способа КОМПАКТНО расположить в ИНДЕКСЕ строки типа 'adir1', 'aadir1','aaadir1','aaaadir1' при наличии строк 'abbb' и 'aaссс'
Цитата
Без like обойтися я не могу, хоть и дерево каталогов разумеется у меня есть в виде именно дерева

ОК, тебе виднее, но - еще раз: like хорош для поиска ПРОИЗВОЛЬНОЙ строки в ПРОИЗВОЛЬНОМ тексте. Дерево НЕ является произвольной структурой и в данный момент времени может быть описано конечным (читай - НЕ произвольным) словарем. В файлах (больших и многих) искать по like вообще, ИМХО, смерти подобно. Но ведь ты и заинтересовался CONTEXT как более приемлемой альтернативой, не так ли? Так вот в CONTEXT тоже есть нечто вроде like - wildcard '%' , его применение и здесь может сильно сказаться на быстродействии :(
Цитата
Когда-ж все-ж эффективен CONTEXT? - когда строки имеют слова??? - т.е. бъются на слова пробелом - разделителем?

Для того, что ты называешь словом, Oracle использует термин token, процесс разбиения текста весьма похож на Java Tokenizer - что объявишь разделителем, то и будет smile См. например описание BASIC_LEXER. Token'ы и используются при индексации.
Цитата
Чем различается сторока текста в MS Word от полного пути каталогов? - я по сути разницы не вижу

Собственно, сравнивать нужно plain text из MS Word и путь...
Объяви для пути '/' как whitespace (одновременно запретив пробелу быть разделителем) - и разницы не будет smile Возможно, тогда и ускорение проявится.
ava
Sleepy_PIP | 07.02.2005, 09:22 #
Цитата (igon @ 6.2.2005, 23:47)
Цитата
like('%...') никогда не будет использовать никакой индекс.


like('/%...') - может использовать индекс, т.к. подстрока поиска имеет предопределенное _начало_.
Ты имеешь в виду это?

Цитата
Pattern Matching on Indexed Columns


When you use LIKE to search an indexed column for a pattern, Oracle can use the index to improve the statement's performance if the leading character in the pattern is not "%" or "_". In this case, Oracle can scan the index by this leading character. If the first character in the pattern is "%" or "_", the index cannot improve the query's performance because Oracle cannot scan the index.


Но:

1. Oracle сканирует только часть индекса, именно ту, для которой строки начинаются с "предопределенного" символа. Игнорирование остальной части естественно даст выигрыш в производительности.

2. У тебя ВСЕ строки начинаются с '/', поэтому сканирование индекса будет полным, без выигрыша в производительности, хотя в плане подключение индекса будет видно.

3. Преимуществом индексирования является возможность разместить в индексе записи, удовлетворяющие условиям поиска, ПОСЛЕДОВАТЕЛЬНО, "компактно" - при выходе за пределы компактного "проживания" поиск можно прекратить. Однако я не вижу способа КОМПАКТНО расположить в ИНДЕКСЕ строки типа 'adir1', 'aadir1','aaadir1','aaaadir1' при наличии строк 'abbb' и 'aaссс'

Цитата
Без like обойтися я не могу, хоть и дерево каталогов разумеется у меня есть в виде именно дерева


ОК, тебе виднее, но - еще раз: like хорош для поиска ПРОИЗВОЛЬНОЙ строки в ПРОИЗВОЛЬНОМ тексте. Дерево НЕ является произвольной структурой и в данный момент времени может быть описано конечным (читай - НЕ произвольным) словарем. В файлах (больших и многих) искать по like вообще, ИМХО, смерти подобно. Но ведь ты и заинтересовался CONTEXT как более приемлемой альтернативой, не так ли? Так вот в CONTEXT тоже есть нечто вроде like - wildcard '%' , его применение и здесь может сильно сказаться на быстродействии :(

Цитата
Когда-ж все-ж эффективен CONTEXT? - когда строки имеют слова??? - т.е. бъются на слова пробелом - разделителем?


Для того, что ты называешь словом, Oracle использует термин token, процесс разбиения текста весьма похож на Java Tokenizer - что объявишь разделителем, то и будет smile См. например описание BASIC_LEXER. Token'ы и используются при индексации.

Цитата
Чем различается сторока текста в MS Word от полного пути каталогов? - я по сути разницы не вижу


Собственно, сравнивать нужно plain text из MS Word и путь...

Объяви для пути '/' как whitespace (одновременно запретив пробелу быть разделителем) - и разницы не будет smile Возможно, тогда и ускорение проявится.

я-ж говорю - _пока_ полный перебор индекса у меня эффективнее полного перебора таблицы. возможно из-за того, что весь индекс помещается в buffer cache, а данные- нет.

==============
Объяви для пути '/' как whitespace (одновременно запретив пробелу быть разделителем) - и разницы не будет smile Возможно, тогда и ускорение проявится
==============
тогда я не пойму где разделяются каталоги, т.к. имена каталогов так-же содержат пробелы.
ava
Sleepy_PIP | 07.02.2005, 10:53 #
вот конкретика:

3 таблички.


CREATE TABLE site_desc
(site_url VARCHAR2(250) NOT NULL,
idsite NUMBER(*,0) NOT NULL,
description VARCHAR2(250),
comm VARCHAR2(250),
scan_commit NUMBER(*,0),
sync_flg NUMBER(5,0),
onl NUMBER(*,0))
)
/

CREATE TABLE site_dir
(iddir NUMBER(20,0),
idsite NUMBER(*,0),
parent_iddir NUMBER(20,0),
dir_flg NUMBER(*,0),
fdir_name VARCHAR2(4000),
pdir_name VARCHAR2(250))
)
/


CREATE TABLE site_files
(id NUMBER(20,0) NOT NULL,
idsite NUMBER(*,0) NOT NULL,
typ NUMBER(5,0),
iddir NUMBER(20,0),
fname VARCHAR2(250),
fsize NUMBER(20,0))
)
/




ны site_dir.fdir_name создан ctxsys.contents индекс.
селекты
select * from site_dir where upper(fdir_name) like('/%ADOBE%')
и
select * from site_dir where containts(fdir_name,'/%ADOBE%',1)>0
выполняются очень малое время не смотря на явный fullscan в 1-м случае. Все - менее 1 сек.

теперь усложняем запросы.

select
/*+RULE */
ff.ID,
ff.IDSITE,
ff.TYP,
ff.IDDIR,
ff.FNAME,
ff.FSIZE,
fd.PARENT_IDDIR,
fd.DIR_FLG,
fd.FDIR_NAME,
fd.PDIR_NAME,
(fd.fdir_name || ff.fname),
sd.site_url,
sd.onl
from site_desc sd, site_dir fd, site_files ff
where ff.idsite=sd.idsite and ff.iddir=fd.iddir
and upper(fd.fdir_name) like('/%ADOBE%')

выполняется примерно 10 сек.
план:
(1) SELECT STATEMENT HINT: RULE
Est. Rows: 100 Cost: 483
(7) HASH JOIN
Est. Rows: 100 Cost: 483
(5) TABLE ACCESS BY INDEX ROWID PIP.SITE_FILES [Not Analyzed]
(5) Est. Rows: 1 Cost: 2
Tablespace: PIP
(4) NESTED LOOPS
Est. Rows: 100 Cost: 473
(2) TABLE ACCESS FULL PIP.SITE_DIR [Not Analyzed]
(2) Est. Rows: 100 Cost: 273
Tablespace: PIP
(3) NON-UNIQUE INDEX RANGE SCAN PIP.SITE_FILES_I3 [Not Analyzed]
Est. Rows: 1 Cost: 1
(6) TABLE ACCESS FULL PIP.SITE_DESC [Not Analyzed]
(6) Est. Rows: 2 000 Cost: 2
Tablespace: PIP

второй запрос

select
/*+RULE */
ff.ID,
ff.IDSITE,
ff.TYP,
ff.IDDIR,
ff.FNAME,
ff.FSIZE,
fd.PARENT_IDDIR,
fd.DIR_FLG,
fd.FDIR_NAME,
fd.PDIR_NAME,
(fd.fdir_name || ff.fname),
sd.site_url,
sd.onl
from site_desc sd, site_dir fd, site_files ff
where ff.idsite=sd.idsite and ff.iddir=fd.iddir
and contains(fd.fdir_name,'/%ADOBE%',1)>0

план:

(1) SELECT STATEMENT HINT: RULE
Est. Rows: 1 Cost: 6
(9) TABLE ACCESS BY INDEX ROWID PIP.SITE_FILES [Not Analyzed]
(9) Est. Rows: 1 Cost: 2
Tablespace: PIP
(8) NESTED LOOPS
Est. Rows: 1 Cost: 6
(6) MERGE JOIN CARTESIAN
Est. Rows: 1 Cost: 4
(3) TABLE ACCESS BY INDEX ROWID PIP.SITE_DIR [Not Analyzed]
(3) Est. Rows: 1 Cost: 2
Tablespace: PIP
(2) DOMAIN INDEX PIP.SITE_DIR_CTX Cost:
(5) BUFFER SORT
Est. Rows: 1 Cost: 2
(4) TABLE ACCESS FULL PIP.SITE_DESC [Not Analyzed]
(4) Est. Rows: 1 Cost: 2
Tablespace: PIP
(7) NON-UNIQUE INDEX RANGE SCAN PIP.SITE_FILES_I1 [Not Analyzed]
Est. Rows: 1 Cost: 1

(как видим full scan-а по site_dir уже нет).
Выполняется более 30 мин. точнее - я не дождался.

Что характерно - оптимизация _только_ COST в обеих запросах, не смотря ни на что.

вот так вот. так что я опять не понимаю - для чего ctssys.context???

ava
igon | 07.02.2005, 16:11 #
Чем дальше в лес, тем толще партизаны smile
1. Что-то не стыкуется:
Цитата
создания этого индекса все планы съезжают на COST оптимизацию

Цитата
оптимизация _только_ COST в обеих запросах

-> в первом запросе CONTEXT нет, a COST - есть -> CONTEXT - не причина COST
2.
Цитата
Oracle automatically uses cost-based optimization with parallel execution.

If ... one of the tables specified in the query requires ... full table scan,
оптимизатор выберет параллельное исполнение.
В Execution Plan обоих запросов видим
Цитата
(4) TABLE ACCESS FULL PIP.SITE_DESC

-> "сползание" на CBO вроде и должно быть
Попробуй

from site_desc sd, site_dir fd, site_files ff
where ff.idsite=sd.idsite and ff.iddir=fd.iddir
--and upper(fd.fdir_name) like('/%ADOBE%') -- Закомментировано!

ИМХО, все равно будет COST оптимизация
3. Никак мне не удается сподвигнуть тебя на отказ от like и wildcard, хотя бы на период тестирования smile Попробуй для CONTEXT искать конкретный token, скажем, 'Adobe Photoshop' - думаю, 30 минут ждать не придется. Заодно проверишь правильность формирования индекса.
4.
Цитата
тогда я не пойму где разделяются каталоги, т.к. имена каталогов так-же содержат пробелы

Цитата
Indexing breaks your text into tokens, which are usually words.
По умолчанию слово - это последовательность символов между пробелами, сам пробел является разделителем (delimiter).
Для путей default delimiter не годится, т.к. словами в этом случае являются имена папок, включающие и пробелы ('Adobe Photoshop'). delimiter'ом здесь должен быть '/' и ТОЛЬКО он.
Чтобы изменить delimiter, перед созданием индекса

begin
ctx_ddl.create_preference('mylex', 'BASIC_LEXER');
ctx_ddl.set_attribute('mylex', 'whitespace', '/');
end;

Потом сам нидекс

create index site_dir_ctx on site_dir(fdir_name) ) indextype is CTXSYS.CONTEXT parameters ( 'LEXER mylex' );



select * from site_dir where containts(fdir_name,'Adobe Photoshop',1)>0

БЕЗ %!!!!
должен дать ВСЕ пути, в которых присутствует папка 'Adobe Photoshop'!!!






ava
Sleepy_PIP | 07.02.2005, 16:19 #
Цитата (igon @ 7.2.2005, 16:11)
Чем дальше в лес, тем толще партизаны smile

1. Что-то не стыкуется:

Цитата
создания этого индекса все планы съезжают на COST оптимизацию


Цитата
оптимизация _только_ COST в обеих запросах


-> в первом запросе CONTEXT нет, a COST - есть -> CONTEXT - не причина COST

2.
Цитата
Oracle automatically uses cost-based optimization with parallel execution.


If ... one of the tables specified in the query requires ... full table scan,
оптимизатор выберет параллельное исполнение.

В Execution Plan обоих запросов видим

Цитата
(4) TABLE ACCESS FULL PIP.SITE_DESC


-> "сползание" на CBO вроде и должно быть

Попробуй



from site_desc sd, site_dir fd, site_files ff

where ff.idsite=sd.idsite and ff.iddir=fd.iddir

--and upper(fd.fdir_name) like('/%ADOBE%') -- Закомментировано!



ИМХО, все равно будет COST оптимизация

3. Никак мне не удается сподвигнуть тебя на отказ от like и wildcard, хотя бы на период тестирования smile Попробуй для CONTEXT искать конкретный token, скажем, 'Adobe Photoshop' - думаю, 30 минут ждать не придется. Заодно проверишь правильность формирования индекса.

4.

Цитата
тогда я не пойму где разделяются каталоги, т.к. имена каталогов так-же содержат пробелы


Цитата
Indexing breaks your text into tokens, which are usually words.
По умолчанию слово - это последовательность символов между пробелами, сам пробел является разделителем (delimiter).

Для путей default delimiter не годится, т.к. словами в этом случае являются имена папок, включающие и пробелы ('Adobe Photoshop'). delimiter'ом здесь должен быть '/' и ТОЛЬКО он.

Чтобы изменить delimiter, перед созданием индекса



begin

ctx_ddl.create_preference('mylex', 'BASIC_LEXER');

ctx_ddl.set_attribute('mylex', 'whitespace', '/');

end;



Потом сам нидекс



create index site_dir_ctx on site_dir(fdir_name) ) indextype is CTXSYS.CONTEXT  parameters ( 'LEXER mylex' );







select * from site_dir where containts(fdir_name,'Adobe Photoshop',1)>0



БЕЗ %!!!!

должен дать ВСЕ пути, в которых присутствует папка 'Adobe Photoshop'!!!

ага. спасибо. счаз буду пробовать.
только одно замечу -
пока существует индекс ctx ... оптимизация cost всегда. в не зевисимости от запроса.
как только грохаю этот индекс - RULE.
ava
Sleepy_PIP | 07.02.2005, 16:30 #
попробовал. пересоздал индекс по приведенным рекомендациям.
select * from site_dir where contains(fdir_name,'ADOBE PH',1)>0 - не выдает ничерта, как и предпологалось
select * from site_dir where contains(fdir_name,'ADOBE PH%',1)>0 - все хорошо.
select * from site_dir where contains(fdir_name,'ADOBE',1)>0 - все хорошо.

НО!!!!!!
select
/*+RULE */
ff.ID,
ff.IDSITE,
ff.TYP,
ff.IDDIR,
ff.FNAME,
ff.FSIZE,
fd.PARENT_IDDIR,
fd.DIR_FLG,
fd.FDIR_NAME,
fd.PDIR_NAME,
(fd.fdir_name || ff.fname),
sd.site_url,
sd.onl
from site_desc sd, site_dir fd, site_files ff
where ff.idsite=sd.idsite and ff.iddir=fd.iddir
and contains(fd.fdir_name,'ADOBE',1)>0

работает (я опять не дождался, ждал 10 мин) на порядки медленнее чем
fullscan в
select
/*+RULE */
ff.ID,
ff.IDSITE,
ff.TYP,
ff.IDDIR,
ff.FNAME,
ff.FSIZE,
fd.PARENT_IDDIR,
fd.DIR_FLG,
fd.FDIR_NAME,
fd.PDIR_NAME,
(fd.fdir_name || ff.fname),
sd.site_url,
sd.onl
from site_desc sd, site_dir fd, site_files ff
where ff.idsite=sd.idsite and ff.iddir=fd.iddir
and upper(fd.fdir_name) like('/%ADOBE%')


как это можно объяснить??





ava
igon | 08.02.2005, 04:01 #
Воспроизвел твою ситуацию у себя (PIII-800, 512, Oracle 9.0.1)
Во всех 3 таблицах по 100 000 записей, заполнил только поля, участвующие в WHERE, пути сгенерировал искусcтвенно, типа

'/aaa14 bbb14/ccc14 ddd14/eee14 fff14/ggg14 hhh14/aaa14bbb/ccc14ddd/eee14fff/ggg14hhh'

(14 - это IDDIR)
В одной записи (с IDDIR=1701) путь такой -

'/aaa bbb/ccc ddd/Adobe Photoshop/ggg hhh/aaabbb/cccddd/eeefff/ggghhh'

Её и искал, вот результаты, ИМХО, вполне приемлемые - CTX быстрее

----------
select
/*+RULE */
ff.ID,
ff.IDSITE,
ff.TYP,
ff.IDDIR,
ff.FNAME,
ff.FSIZE,
fd.PARENT_IDDIR,
fd.DIR_FLG,
fd.FDIR_NAME,
fd.PDIR_NAME,
(fd.fdir_name || ff.fname),
sd.site_url,
sd.onl
from site_desc sd,
site_dir fd,
site_files ff
where ff.idsite=sd.idsite and
ff.iddir=fd.iddir and
contains(fd.fdir_name,'ADOBE',1)>0

время выполнения - 6,40 сек
------------
select
/*+RULE */
ff.ID,
ff.IDSITE,
ff.TYP,
ff.IDDIR,
ff.FNAME,
ff.FSIZE,
fd.PARENT_IDDIR,
fd.DIR_FLG,
fd.FDIR_NAME,
fd.PDIR_NAME,
(fd.fdir_name || ff.fname),
sd.site_url,
sd.onl
from site_desc sd,
site_dir fd,
site_files ff
where ff.idsite=sd.idsite and
ff.iddir=fd.iddir and
upper(fd.fdir_name) like('/%ADOBE%')

время выполнения - 6,73 сек
-----

Почему у тебя разница на порядки - хм, даже и не представляю :(

Кстати,
Цитата
The predefined default values for whitespace are 'space' and 'tab'. These values cannot be changed. Specifying characters as whitespace characters adds to these defaults.

Т.е. пробелы как разделители запретить не удасться
ava
Sleepy_PIP | 08.02.2005, 08:02 #
Цитата (igon @ 8.2.2005, 04:01)
Воспроизвел твою ситуацию у себя (PIII-800, 512, Oracle 9.0.1)

Во всех 3 таблицах по 100 000 записей, заполнил только поля, участвующие в WHERE, пути сгенерировал искусcтвенно, типа



'/aaa14 bbb14/ccc14 ddd14/eee14 fff14/ggg14 hhh14/aaa14bbb/ccc14ddd/eee14fff/ggg14hhh'



(14 - это IDDIR)

В одной записи (с IDDIR=1701) путь такой -


'/aaa bbb/ccc ddd/Adobe Photoshop/ggg hhh/aaabbb/cccddd/eeefff/ggghhh'



Её и искал, вот результаты, ИМХО, вполне приемлемые - CTX быстрее



----------

select

/*+RULE */

ff.ID,

ff.IDSITE,

ff.TYP,

ff.IDDIR,

ff.FNAME,

ff.FSIZE,

fd.PARENT_IDDIR,

fd.DIR_FLG,

fd.FDIR_NAME,

fd.PDIR_NAME,

(fd.fdir_name || ff.fname),

sd.site_url,

sd.onl

from site_desc sd,
      site_dir fd,
      site_files ff

where ff.idsite=sd.idsite and
       ff.iddir=fd.iddir and

contains(fd.fdir_name,'ADOBE',1)>0



время выполнения - 6,40 сек

------------

select

/*+RULE */

ff.ID,

ff.IDSITE,

ff.TYP,

ff.IDDIR,

ff.FNAME,

ff.FSIZE,

fd.PARENT_IDDIR,

fd.DIR_FLG,

fd.FDIR_NAME,

fd.PDIR_NAME,

(fd.fdir_name || ff.fname),

sd.site_url,

sd.onl

from site_desc sd,
      site_dir fd,
      site_files ff

where ff.idsite=sd.idsite and
       ff.iddir=fd.iddir and

upper(fd.fdir_name) like('/%ADOBE%')



время выполнения - 6,73 сек

-----



Почему у тебя разница на порядки - хм, даже и не представляю :(



Кстати,

Цитата
The predefined default values for whitespace are 'space' and 'tab'. These values cannot be changed. Specifying characters as whitespace characters adds to these defaults.


Т.е. пробелы как разделители запретить не удасться

а!. это от того, что у тебя связанная табличка site_files ff
пустая.
у меня в site_dir - 50000 записей, а в site_files - 3.5М записей ...
счаз попробую ее почистить, посмотрю что будет ...

пардон, не внимательно прочел начало мессага.
ava
Sleepy_PIP | 08.02.2005, 10:03 #
кажется все стало ясно.
Завел в site_dir еще одно поле - fdir_names, куда подложил replace(fdir_name,'/'.' /')
тоесть заменил все '/' на ' /'(с пробелом).
Перестроил ctx индекс.
Теперь запрос по contains(fdir_names,'ADOBE',1) выполняется 28 сек, запрос с like - 31 сек.
Времена вообщем-то сравнимые.
Но это показывает что interMedia Text можно использовать только на данных, разделителем в которых является пробел ...
хм. ...
ava
igon | 08.02.2005, 14:41 #
Цитата
Но это показывает что interMedia Text можно использовать только на данных, разделителем в которых является пробел

Нет, ни в коем случае!, '/' в данной ситуации тоже рассматривается как разделитель, иначе contains(fdir_names,'ADOBE',1) ничего не найдет, так как фрагмент пути выглядит как '... /ADOBE ...' и token`ом является (как ты считаешь!!!) '/ADOBE'
Если ты создал и использовал при генерации индекса mylex, то текущий список используемых разделителей включает ТРИ символа - '<space>', '<tab>' и '/'
Так что replace(fdir_name,'/'.' /') совершенно лишнее телодвижение, пожалуй, даже вредное: два разделителя подряд - это мусор, который все равно надо обрабатывать.

Общее впечатление от CTX - монстр (надо же - забабахал мне в пользовательскую схему 4 довольно упитанных таблицы!!!), тяжелая артиллерия, пушка, "заточенная" на оптимальный поиск в БОЛЬШИХ и МНОГИХ документах благодаря индексации их текстов. Твои пути - это все-таки, ИМХО, воробьи smile

Цитата
Теперь запрос по contains(fdir_names,'ADOBE',1) выполняется 28 сек, запрос с like - 31 сек.

Времена вообщем-то сравнимые

Пора переходить на wildcard в contains, чтобы прекратить это безобразие с сопоставимостью времен smile
ava
Sleepy_PIP | 08.02.2005, 17:15 #
Цитата (igon @ 8.2.2005, 14:41)
Цитата
Но это показывает что interMedia Text можно использовать только на данных, разделителем в которых является пробел


Нет, ни в коем случае!, '/' в данной ситуации тоже рассматривается как разделитель, иначе contains(fdir_names,'ADOBE',1) ничего не найдет, так как фрагмент пути выглядит как '... /ADOBE ...' и token`ом является (как ты считаешь!!!) '/ADOBE'

Если ты создал и использовал при генерации индекса mylex, то текущий список используемых разделителей включает ТРИ символа - '<space>', '<tab>' и '/'

Так что replace(fdir_name,'/'.' /') совершенно лишнее телодвижение, пожалуй, даже вредное: два разделителя подряд - это мусор, который все равно надо обрабатывать.



Общее впечатление от CTX - монстр (надо же - забабахал мне в пользовательскую схему 4 довольно упитанных таблицы!!!), тяжелая артиллерия, пушка, "заточенная" на оптимальный поиск в БОЛЬШИХ и МНОГИХ документах благодаря индексации их текстов. Твои пути - это все-таки, ИМХО, воробьи smile



Цитата
Теперь запрос по contains(fdir_names,'ADOBE',1) выполняется 28 сек, запрос с like - 31 сек.


Времена вообщем-то сравнимые


Пора переходить на wildcard в contains, чтобы прекратить это безобразие с сопоставимостью времен smile

тем не менее находит ...

я пробовал как по рекомендации
begin
ctx_ddl.create_preference('mylex', 'BASIC_LEXER');
ctx_ddl.set_attribute('mylex', 'whitespace', '/');
end;

1-й раз отиндексировал fdir_name (без пробелов перед '/').
Результат никакой - т.е. поиск по contains более 10 мин. , по like - 10-20 сек.

2-й раз я отиндексировал fdir_names (т.е. с пробелами перед '/')
Вот тут время выполнения contains и like сравнялось.

Искал все время ADOB в обеих случаях все находится нормально .....
ava
igon | 09.02.2005, 01:39 #
Цитата
тем не менее находит ...

Хм, странно... Подозреваю, что у тебя что-то не в порядке с полем fdir_name.
Попробуй убрать добавленные пробелы в fdir_names и опять сделать поиск. По идее, при этом индекс пересоздавать не нужно - он будет обновляться "на лету", но, возможно, ну оооочень долго.
Или прибей индекс, удали пробелы и пересоздай индекс.
Кстати, какие tokens у тебя наопределялись в dr$site_dir_ctx$i, поле token_text ? Предвижу, что среди них НЕТ содержащих '/' !!!
ava
Sleepy_PIP | 09.02.2005, 10:08 #
Цитата (igon @ 9.2.2005, 01:39)
Цитата
тем не менее находит ...


Хм, странно... Подозреваю, что у тебя что-то не в порядке с полем fdir_name.

Попробуй убрать добавленные пробелы в fdir_names и опять сделать поиск. По идее, при этом индекс пересоздавать не нужно - он будет обновляться "на лету", но, возможно, ну оооочень долго.

Или прибей индекс, удали пробелы и пересоздай индекс.

Кстати, какие tokens у тебя наопределялись в dr$site_dir_ctx$i, поле token_text ? Предвижу, что среди них НЕТ содержащих '/' !!!

сначала посмотерел что лежит если с пробелами.
лежит типа:

"ADOBE",0,605,167424,756,
"ADOBE",0,167717,214262,261,
"ADOBEDIMENSIONS3.0TRYOUTPATCHBIDJAN",0,64981,64981,1,
"ADOBEPHOTOSHOP7",0,71446,71446,1,
"ADOBEPHOTOSHOP7RUS",0,66699,116687,3,
"ADOBEPHOTOSHOP7RUS",0,180157,204396,3,
"ADOBEPREMIER",0,117963,149779,4,
"ADOBEPREMIER",0,201427,201429,2,
"ADOBEPREMIERE",0,35933,164296,20,
"ADOBEPSDRIVERINSTALLER",0,162407,162407,1,
"ADOBEQUESTIONSANDANSWERS",0,29310,156580,14,
"ADOBESTD",0,29059,157233,39,
"ADOBESTD",0,191255,195469,8,

теперь без пробелов:

"ADOBE",0,605,167424,756,
"ADOBE",0,167717,214262,261,
"ADOBEDIMENSIONS3.0TRYOUTPATCHBIDJAN",0,64981,64981,1,
"ADOBEPHOTOSHOP7",0,71446,71446,1,
"ADOBEPHOTOSHOP7RUS",0,66699,116687,3,
"ADOBEPHOTOSHOP7RUS",0,180157,204396,3,
"ADOBEPREMIER",0,117963,149779,4,
"ADOBEPREMIER",0,201427,201429,2,
"ADOBEPREMIERE",0,35933,164296,20,
"ADOBEPSDRIVERINSTALLER",0,162407,162407,1,
"ADOBEQUESTIONSANDANSWERS",0,29310,156580,14,
"ADOBESTD",0,29059,157233,39,
"ADOBESTD",0,191255,195469,8,

выборка
SELECT a.token_text, a.token_type, a.token_first, a.token_last,
a.token_count, a.token_info
FROM dr$site_dir_ctx$i a
where token_text like('ADOBE%')

т.е. токены лежат абсолютно те-же ...

в случае с пробелами перед '/' выборка
SELECT a.token_text, a.token_type, a.token_first, a.token_last,
a.token_count, a.token_info
FROM dr$site_dir_ctx$i a
where token_text like('%ADOBE%')
дает
"ADOBE",0,605,167424,756,
"ADOBEDIMENSIONS3.0TRYOUTPATCHBIDJAN",0,64981,64981,1,
"ADOBEPHOTOSHOP7",0,71446,71446,1,
"ADOBEPHOTOSHOP7RUS",0,66699,116687,3,
"ADOBEPREMIER",0,117963,149779,4,
"ADOBEPREMIERE",0,35933,164296,20,
"ADOBEPSDRIVERINSTALLER",0,162407,162407,1,
"ADOBEQUESTIONSANDANSWERS",0,29310,156580,14,
"ADOBESTD",0,29059,157233,39,
"ADOBE",0,167717,214262,261,
"ADOBEPHOTOSHOP7RUS",0,180157,204396,3,
"ADOBEPREMIER",0,201427,201429,2,
"ADOBESTD",0,191255,195469,8,

т.е. '/' не включается.
ava
igon | 09.02.2005, 11:26 #
Угу, "предсказания" сбылись smile
Но для
Цитата
теперь без пробелов:

мне интересней выборка
Цитата
from site_desc sd, site_dir fd, site_files ff

where ff.idsite=sd.idsite and ff.iddir=fd.iddir

and contains(fd.fdir_nameS,'ADOBE',1)>0

т.е. результат вот этого
Цитата
Попробуй убрать добавленные пробелы в fdir_names и опять сделать поиск.


BTW, если при создании индекса ты НЕ БУДЕШЬ использовать mylex, в списке token'ов ПОЯВЯТСЯ содержащие '/'
ava
Sleepy_PIP | 09.02.2005, 12:10 #
Цитата (igon @ 9.2.2005, 11:26)
Угу, "предсказания" сбылись smile

Но для

Цитата
теперь без пробелов:


мне интересней выборка

Цитата
from site_desc sd, site_dir fd, site_files ff


where ff.idsite=sd.idsite and ff.iddir=fd.iddir


and contains(fd.fdir_nameS,'ADOBE',1)>0


т.е. результат вот этого

Цитата
Попробуй убрать добавленные пробелы в fdir_names и опять сделать поиск.




BTW, если при создании индекса ты НЕ БУДЕШЬ использовать mylex, в списке token'ов ПОЯВЯТСЯ содержащие '/'

расскажи как избавитьься теперь от mylex, а?
я буду пробовать ...
ava
igon | 10.02.2005, 01:43 #
Цитата
как избавитьься теперь от mylex

при создании (пересоздании) индекса просто его не указываешь в параметрах
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
  guest   Sleepy_PIP   igon
advanced
Submit