![]() |
|
Модераторы: LSD |
![]()
|
|
| Sleepy_PIP |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: нет Всего: 12 |
ORA 9.2
Имеется простая табличка:
в которой поле fdir_name содержит полное имя каталога FTP серверов (т.е. от корня '/' до пследнего каталога... т.е. например '/subruut/dir1/dir2/last_dir'). есть некий набор запросов (прямых, и через view) с условием на это поле like('/%...%') Статистика сброшена. План - по RULE. вполне удовлетворяющий план. Теперь пытаюсь навесить на это поле CTXSYS.CONTEXT тип индекса как:
после создания этого индекса все планы съезжают на COST оптимизацию, совсем мне не нужную. full scan по site_dir появляется, и время выполнения запросов резко возрастает. Сбрасываю этот индекс - все возвращяется в норму. Сколько не читал про CTXSYS.CONTEXT - везде пишут что это типа здорово и как раз приминимо для оптимизации текстового поиска. Но практика показывает другое. В чем я не прав? Почему наблюдается только ухудшение? Спасибо! -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
||||
|
|||||
| igon |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 327 Регистрация: 30.10.2004 Репутация: 7 Всего: 21 |
Возможно, не совсем уместно для анализа достаточно коротких строк (даже если твои пути могут быть длиной до 4000 символов, что само по себе удивительно
Если же в fdir_name хранятся URL и предполагается анализировать не компоненты пути, а содержимое файла, на который указывает URL, то
Кроме того, для context индексов в запросах применяется CONTAINS, но не like. Что-то я вообще не представляю совместную эффективность like и индексированного поля. И как тебе удается избежать full scan при наличии в запросе like('/%...%'), даже без индекса. -------------------- Хотите поговорить об этом? |
|||
|
||||
| Sleepy_PIP |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: нет Всего: 12 |
ну во первых like('/%...') - идет поиск все-ж по индесксу, т.к. 1-й символ предопределен. Можно спорить что при этом эффективнее - обход всего дерева, или full scan по данным. Но пока индекс эффективнее по практическим замерениям. а во вторых - я не понимаю сути CTXSYS.CONTEXT индекса. Он что - бъет строку на слова? (слов-то у меня и нет - просто длинная сторка). В третьих - почему при исползовании CONTEXT план съезжает на cost и никакие хинты на него не действуют? Т.е. для меня пока так и остается на понятным - когда CONTEXT эффективен? для каких типов данных и запросов он эффективен? PS: хранятся у меня там строки вида: '/subruut/dir1/dir2/.../last_dir' ... вот в таком духе. -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
||||
|
|||||
| igon |
|
||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 327 Регистрация: 30.10.2004 Репутация: 7 Всего: 21 |
Предопределенность 1-го символа вряд ли имеет значение - like('/%dir2%') должен будет найти подстроку, которая может находиться в ЛЮБОЙ позиции исходной строки, начинающейся с '/'. Какая же здесь польза от индексирования? ИМХО, CTXSYS.CONTEXT к замедлению может и не иметь отношения: попробуй создать обыкновенный индекс на поле и посмотреть, что будет с планом для запроса с like.
О существовании Oracle Text я узнал благодаря твоему вопросу Может быть, стоит переосмыслить подход? В первую очередь постараться избавиться от like - фактически очень трудоемкой операции, применение которой допустимо, только если уже ничто другое придумать не удается. Мне сложно судить о твоей задаче (именно, что может находиться между %% и "однообразие" структуры путей), но возможный вариант - создание а ля dictionary для стандартных компонентов путей и поиск в них, но уже не через 'like', а '='.
Можно даже создать словарь для ВСЕХ возможных строк поиска, тогда в подзапросе достаточно будет одного равенства -------------------- Хотите поговорить об этом? |
||||||||||
|
|||||||||||
| Guest |
|
||||||||||||
|
Unregistered |
like('%...') никогда не будет использовать никакой индекс. like('/%...') - может использовать индекс, т.к. подстрока поиска имеет предопределенное _начало_. На практике так и происходит. Без like обойтися я не могу, хоть и дерево каталогов разумеется у меня есть в виде именно дерева. Задача простая - FTP search по паттернам. паттрены - произвольные. поиск и в полных путях каталогов и в файлах. Когда-ж все-ж эффективен CONTEXT? - когда строки имеют слова??? - т.е. бъются на слова пробелом - разделителем? Я имею набор строк с и без пробелами. длинны - до 2000 символов. Но так и не разобрался пока. Последние пробы - использовал оператор contains, проедварительно построив нужный индекс. Никакого ускорения аналогичных с like запросов не увидел. План кстати посмотреть в SQL Navigator-е с contains не получается. а план запросов с like сехал на cost и времы возросло в порядки. Т.е. я опять не понимаю где CONTEXT будет эффективен?? Чем различается сторока текста в MS Word от полного пути каталогов? - я по сути разницы не вижу. |
||||||||||||
|
|||||||||||||
| igon |
|
||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 327 Регистрация: 30.10.2004 Репутация: 7 Всего: 21 |
Но: 1. Oracle сканирует только часть индекса, именно ту, для которой строки начинаются с "предопределенного" символа. Игнорирование остальной части естественно даст выигрыш в производительности. 2. У тебя ВСЕ строки начинаются с '/', поэтому сканирование индекса будет полным, без выигрыша в производительности, хотя в плане подключение индекса будет видно. 3. Преимуществом индексирования является возможность разместить в индексе записи, удовлетворяющие условиям поиска, ПОСЛЕДОВАТЕЛЬНО, "компактно" - при выходе за пределы компактного "проживания" поиск можно прекратить. Однако я не вижу способа КОМПАКТНО расположить в ИНДЕКСЕ строки типа 'adir1', 'aadir1','aaadir1','aaaadir1' при наличии строк 'abbb' и 'aaссс'
ОК, тебе виднее, но - еще раз: like хорош для поиска ПРОИЗВОЛЬНОЙ строки в ПРОИЗВОЛЬНОМ тексте. Дерево НЕ является произвольной структурой и в данный момент времени может быть описано конечным (читай - НЕ произвольным) словарем. В файлах (больших и многих) искать по like вообще, ИМХО, смерти подобно. Но ведь ты и заинтересовался CONTEXT как более приемлемой альтернативой, не так ли? Так вот в CONTEXT тоже есть нечто вроде like - wildcard '%' , его применение и здесь может сильно сказаться на быстродействии
Для того, что ты называешь словом, Oracle использует термин token, процесс разбиения текста весьма похож на Java Tokenizer - что объявишь разделителем, то и будет
Собственно, сравнивать нужно plain text из MS Word и путь... Объяви для пути '/' как whitespace (одновременно запретив пробелу быть разделителем) - и разницы не будет -------------------- Хотите поговорить об этом? |
||||||||||
|
|||||||||||
| Sleepy_PIP |
|
||||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: нет Всего: 12 |
я-ж говорю - _пока_ полный перебор индекса у меня эффективнее полного перебора таблицы. возможно из-за того, что весь индекс помещается в buffer cache, а данные- нет. ============== Объяви для пути '/' как whitespace (одновременно запретив пробелу быть разделителем) - и разницы не будет ============== тогда я не пойму где разделяются каталоги, т.к. имена каталогов так-же содержат пробелы. -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
||||||||||||
|
|||||||||||||
| Sleepy_PIP |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: нет Всего: 12 |
вот конкретика:
3 таблички.
ны 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??? -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
|||
|
||||
| igon |
|
||||||||||||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 327 Регистрация: 30.10.2004 Репутация: 7 Всего: 21 |
Чем дальше в лес, тем толще партизаны
1. Что-то не стыкуется:
-> в первом запросе CONTEXT нет, a COST - есть -> CONTEXT - не причина COST 2.
В Execution Plan обоих запросов видим
-> "сползание" на CBO вроде и должно быть Попробуй
ИМХО, все равно будет COST оптимизация 3. Никак мне не удается сподвигнуть тебя на отказ от like и wildcard, хотя бы на период тестирования 4.
Для путей default delimiter не годится, т.к. словами в этом случае являются имена папок, включающие и пробелы ('Adobe Photoshop'). delimiter'ом здесь должен быть '/' и ТОЛЬКО он. Чтобы изменить delimiter, перед созданием индекса
Потом сам нидекс
БЕЗ %!!!! должен дать ВСЕ пути, в которых присутствует папка 'Adobe Photoshop'!!! -------------------- Хотите поговорить об этом? |
||||||||||||||||||||
|
|||||||||||||||||||||
| Sleepy_PIP |
|
||||||||||||||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: нет Всего: 12 |
ага. спасибо. счаз буду пробовать. только одно замечу - пока существует индекс ctx ... оптимизация cost всегда. в не зевисимости от запроса. как только грохаю этот индекс - RULE. -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
||||||||||||||||||||||
|
|||||||||||||||||||||||
| Sleepy_PIP |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: нет Всего: 12 |
попробовал. пересоздал индекс по приведенным рекомендациям.
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%') как это можно объяснить?? -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
|||
|
||||
| igon |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 327 Регистрация: 30.10.2004 Репутация: 7 Всего: 21 |
Воспроизвел твою ситуацию у себя (PIII-800, 512, Oracle 9.0.1)
Во всех 3 таблицах по 100 000 записей, заполнил только поля, участвующие в WHERE, пути сгенерировал искусcтвенно, типа
(14 - это IDDIR) В одной записи (с IDDIR=1701) путь такой -
Её и искал, вот результаты, ИМХО, вполне приемлемые - CTX быстрее
Почему у тебя разница на порядки - хм, даже и не представляю Кстати,
Т.е. пробелы как разделители запретить не удасться -------------------- Хотите поговорить об этом? |
||||||||
|
|||||||||
| Sleepy_PIP |
|
||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: нет Всего: 12 |
а!. это от того, что у тебя связанная табличка site_files ff пустая. у меня в site_dir - 50000 записей, а в site_files - 3.5М записей ... счаз попробую ее почистить, посмотрю что будет ... пардон, не внимательно прочел начало мессага. Это сообщение отредактировал(а) Sleepy_PIP - 8.2.2005, 08:08 -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
||||||||||
|
|||||||||||
| Sleepy_PIP |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: нет Всего: 12 |
кажется все стало ясно.
Завел в site_dir еще одно поле - fdir_names, куда подложил replace(fdir_name,'/'.' /') тоесть заменил все '/' на ' /'(с пробелом). Перестроил ctx индекс. Теперь запрос по contains(fdir_names,'ADOBE',1) выполняется 28 сек, запрос с like - 31 сек. Времена вообщем-то сравнимые. Но это показывает что interMedia Text можно использовать только на данных, разделителем в которых является пробел ... хм. ... -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
|||
|
||||
| igon |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 327 Регистрация: 30.10.2004 Репутация: 7 Всего: 21 |
Нет, ни в коем случае!, '/' в данной ситуации тоже рассматривается как разделитель, иначе contains(fdir_names,'ADOBE',1) ничего не найдет, так как фрагмент пути выглядит как '... /ADOBE ...' и token`ом является (как ты считаешь!!!) '/ADOBE' Если ты создал и использовал при генерации индекса mylex, то текущий список используемых разделителей включает ТРИ символа - '<space>', '<tab>' и '/' Так что replace(fdir_name,'/'.' /') совершенно лишнее телодвижение, пожалуй, даже вредное: два разделителя подряд - это мусор, который все равно надо обрабатывать. Общее впечатление от CTX - монстр (надо же - забабахал мне в пользовательскую схему 4 довольно упитанных таблицы!!!), тяжелая артиллерия, пушка, "заточенная" на оптимальный поиск в БОЛЬШИХ и МНОГИХ документах благодаря индексации их текстов. Твои пути - это все-таки, ИМХО, воробьи
Пора переходить на wildcard в contains, чтобы прекратить это безобразие с сопоставимостью времен -------------------- Хотите поговорить об этом? |
||||
|
|||||
![]()
|
| Правила форума "Oracle" | |
|
|
Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Oracle | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |