Текущий архив: 2004.09.12;
Скачать: CL | DM;
Вниз
Зависает FireBird Найти похожие ветки
← →
galexis © (2004-08-18 11:27) [0]Поиск в БД идет несколько минут (1-2 минуты). Особо нетерпеливые пользователи, видя что программа не реагирует на их дейтвия вырубают ее по ctrl+alt+del. После чего зависает FireBird Server на сервере. Точнее в службах написано, что он работает, а подключится к нему не удается. Приходится останавливать службу и запускать ее заново. Что не так?
Спасибо.
← →
Соловьев © (2004-08-18 11:28) [1]
> Поиск в БД идет несколько минут (1-2 минуты).
вывести окошко. Идет поиск :)
И интересно посмотреть на этот поиск - что же там можно 2 минуты делать то?
← →
galexis © (2004-08-18 11:36) [2]Да по этому поиску я тут уже общался. Идет поиск с помощью Like в поле VARCHAR длиной 400. И окошко есть, и курсор на часы с SQL поменял. Не могу особо тупых пользователей поменять.
← →
Anatoly Podgoretsky © (2004-08-18 11:40) [3]Докладную записку директору
← →
Соловьев © (2004-08-18 11:42) [4]
> Идет поиск с помощью Like в поле VARCHAR длиной 400
не помню там требовалось только поиск с начала строки или по всей?
← →
Desdechado © (2004-08-18 11:42) [5]так и сервер наверно не зависает, а продолжает этот запрос обрабатывать, может, даже захватывая все ресурсы процессора
← →
galexis © (2004-08-18 11:53) [6]
> Соловьев ©
Поиск на вхождение слова или части слова по всей строке. Это БД юр. лиц. Обычно ищут то, чего сами не знают.
> Desdechado ©
Может и так. Но обычно запрос длится не более 2 минут. А после отрубания программы, FireBird и через 30 минут не работает. Да и сервак достаточно мощный двухпроцессорный на Xion 2,4 ГГц, 2Гб оперативки, RAID и т.д. Фирменный - IBM.
← →
Digitman © (2004-08-18 11:54) [7]
> Не могу особо тупых пользователей поменять
они далеко не всегда тупые, просто они как правило излишне ретивые)
и вот предупредить их ретивость ты вполне бы мог внесением специальной логики в свою программу
мало того, ты как программер обязан предусматривать подобные ситуации !
1. Предусмотри возможность изменения привелегий твоего процесса, так чтобы его снятие с выполнения было возможно только с административными или иными спец.правами
2. Вынеси потенциально "тяжелый" запрос в доп.трэд, чтобы не занимать им осн.трэд
3. Вынеси формирование НД по этому запросу в ХП
В сам запрос добавь проверку значения специально созданного тобой генератора
for select .... into ... where .... and GEN_ID(GEN, 0) = 0 do suspend;
перед обращением к ХП сбрось генератор GEN в 0
обратись к ХП (т.е. стартуй запрос) в доп.треде, в осн.трэде выведи модальное окошко с прогресс-баром или анимацией и кнопкой ОТМЕНА
когда ретивый юзер устанет ждать, он кликнет на кнопке ОТМЕНА, при этом ты стартуешь еще один доп.тред, задача которого - инкрементировать генератор GEN
как только при выборке очер.записи ХП обнаружит условие GEN_ID(GEN, 0) <> 0, выполнение запроса немедленно и корректно прекращается, и метод StoredProc.Open, вызванный в доп.треде, немедленно возвратит управление
← →
Sergey_Masloff (2004-08-18 12:01) [8]galexis © (18.08.04 11:53) [6]
>Поиск на вхождение слова или части слова по всей строке. Это БД >юр. лиц. Обычно ищут то, чего сами не знают.
Если ты ищешь лайком с процентиком впереди то лучше им искать другого программиста. Не обижайся, но мир суров.
Для описаной тобой задачи имеются совершенно другие способы. Могу сказать что у нас поиск по многомиллионной базе клиентов по нечеткому критерию идет ну 2-3 секунды. Причем найдет даже если ты вместо Иванов ищешь Ивнов например (ну ошибся при вводе). Но это так, уже мерянье.
По сабжу реализуй словарь и поиск через него. Типа название ООО Рога и Копыта -> ООО на фиг в словарь идет две записи "Рога" и "Копыта". Первый поиск идет по словарю возвращаешься по ссылкам на основнуютаблицу проверяя процент соответствия. Это решение лежащее на поверхности.
← →
Соловьев © (2004-08-18 12:06) [9]
> на фиг в словарь идет две записи "Рога" и "Копыта". Первый
> поиск идет по словарю возвращаешься по ссылкам на основнуютаблицу
> проверяя процент соответствия. Это решение лежащее на поверхности.
Да, и еще хочу добавить, что как правило то исчут без учета регистра - так вот в справочнике еще предусмотреть несколько полей, одно как есть, а другое в верхнем регистре - и искать без % с начала, тогда можно индекс подключить
← →
Anatoly Podgoretsky © (2004-08-18 12:11) [10]Соловьев © (18.08.04 12:06) [9]
SOUNDEX его давно придумали американцы
← →
Соловьев © (2004-08-18 12:13) [11]
> OUNDEX его давно придумали американцы
это понятно - для нечеткого поиска. я про другое говорил.
← →
galexis © (2004-08-18 12:17) [12]
> Digitman ©
Программист я хреновый, т.к. занимаюсь этим от случая к случаю. Давно хотел сделать поиск как в IB Expert. Но не умею. Мне бы где подробнее почитать про эти нити и т.д. Я даже не все понял, про что вы написали НД, ХП. ХП -хранимая процедура? НД-?
> Sergey_Masloff
Да я и сам знаю что хреновый программист. Но какой уж есть. Тем более что в нашей организации их вообще нет, а я системный администратор наверно. А каким образом словарь формировать? Отдельной программкой?
← →
Sergey_Masloff (2004-08-18 12:30) [13]galexis © (18.08.04 12:17) [12]
>А каким образом словарь формировать? Отдельной программкой
Почему отдельной? Зависит от используемой "стратегии"
Это можно делать при вставке каждой записи. Логика может быть реализована как на клиенте так и на сервере (если он поддерживает) - как ХП или триггер например. Неважно.
В твоей ситуации может быть будет какая-то утилитка (отдельная или вмонтированая в программу) которая пробежит по имеющейся базе и построит словарь.
Суть ты (я думаю) понял - строка разбивается на слова и незначащие (ООО, АОЗТ, ТОО и так далее а также предлоги) - выкидываем. Значащие пишем в отдельную таблицу - словарь в которой три (например) поля - ID (уникальный) PARENTID (ссылка на ключ основной таблицы) и VALUE (слово)
Таблица MAIN
ID NAME
1 АОЗТ Рога И Копыта
Таблица DICTIONARY
ID PARENTID VALUE
1 1 РОГА <-- Регистр ВСЕГДА один!!!
2 1 КОПЫТА
В поиске пляшешь от словаря
← →
galexis © (2004-08-18 12:31) [14]
> Соловьев ©
я и перевожу сначало все в верхний регистр. Это значит что мне без % надо искать?
← →
Sergey13 © (2004-08-18 12:34) [15]2 [13] Sergey_Masloff (18.08.04 12:30)
У автора
>Идет поиск с помощью Like в поле VARCHAR длиной 400
Для 400 таких слов штук 40 с гаком может быть. Если записей прилично, то... 8-(
← →
Sergey_Masloff (2004-08-18 12:34) [16]galexis © (18.08.04 12:31) [14]
>Это значит что мне без % надо искать
нет но это значит что ты уже на верном пути
← →
Digitman © (2004-08-18 12:36) [17]
> НД-?
Набор Данных
← →
Sergey13 © (2004-08-18 12:36) [18]2 galexis ©
А что это за поле 400 символов?
← →
Соловьев © (2004-08-18 12:37) [19]
> Это значит что мне без % надо искать?
where field_dic starting "РОГ" или where field_dic like "РОГ%"
подключит индекс и будет искать все слова которые начинаются на РОГ
← →
Sergey13 © (2004-08-18 12:40) [20]2[19] Соловьев © (18.08.04 12:37)
На поле 400 символов вроде индекс не повесишь. Там вроде ограничение около 80 - не помню. Хотя может я и ошибаюсь.
← →
Соловьев © (2004-08-18 12:42) [21]
> На поле 400 символов вроде индекс не повесишь. Там вроде
> ограничение около 80 - не помню. Хотя может я и ошибаюсь.
конечно не повесиш, я мею ввиду таблицу справочник слов.
← →
galexis © (2004-08-18 12:48) [22]>Соловьев © Да я не могу почемуто создать индекс по этому полю.
>Sergey13 Записей действительно 60 тыс. И слов много. Плюс оказывается в названии юр. лиц могут встречаться знаки препинания, например запятые.
← →
galexis © (2004-08-18 12:52) [23]
> Sergey_Masloff
А как разбивать поле на слова? В голову приходит только посимвольное копирование до пробела или еще до чего нибудь. Думаю создание словаря выльется часов в 10.
← →
Sergey_Masloff (2004-08-18 12:52) [24]galexis © (18.08.04 12:48) [22]
>я не могу почемуто создать индекс
Ну не почему-то а потому что ограничение 255 байт а символы мультибайтовые то есть 255/3 = макс. размер индекса дла русского чарсета
>Записей действительно 60 тыс
Для интербейза это копейки
>Плюс оказывается в названии юр. лиц могут встречаться знаки >препинания, например запятые
Для поиска нужно выкидывать все несущественное. Даже если слов 40 поисковозначимых из них ну 10 (сходу даже пример такой придумать трудно). Как правило 2-5 слов получается в словаре.
← →
Sergey_Masloff (2004-08-18 12:54) [25]galexis © (18.08.04 12:52) [23]
>А как разбивать поле на слова? В голову приходит только >посимвольное копирование до пробела или еще до чего нибудь. >Думаю создание словаря выльется часов в 10.
Да хоть в 100. Это операция одноразовая. Главно потом делать это на каждую вставляемую запись.
← →
Соловьев © (2004-08-18 12:55) [26]
> Да я не могу почемуто создать индекс по этому полю
по какому?
← →
galexis © (2004-08-18 13:19) [27]>Sergey_Masloff
Поиск идет тоже не по одному слову. Например, есть ООО "Русская промышленная компания". Пользователь вводит Русская компания. Каким образом в словаре вести поиск?
← →
Digitman © (2004-08-18 13:43) [28]
> galexis
формирование слов.статей и "индексов" по ним веди в триггерах на вставку/модификацию
каждая слов.статья должна ссылаться на список точных координат ее вхождения в конкретные записи и хэш-таблицу
вообще говоря, хранить данные для поиска лучше всего будет в БЛОБ-поле, а ф-цию поиска (на базе формируемого словаря) осуществлять в UDF, т.к. производительность поиска в БЛОБ-данных ощутимо эффективней, если она ведется в UDF (т.е. алгоритм поиска полностью подконтролен и реализован в оптимизированном маш.коде)
← →
Iconka © (2004-08-18 13:43) [29]наверно
...
name = "Русская"
or name = "компания"
...
← →
Sergey_Masloff (2004-08-18 14:00) [30]galexis © (18.08.04 13:19) [27]
CREATE TABLE DICTITBL (
ID INTEGER NOT NULL,
PARENTID INTEGER NOT NULL,
STRVALUE VARCHAR(40) NOT NULL
);
CREATE TABLE MAINTABLE (
ID INTEGER NOT NULL,
NAME VARCHAR(400)
);
ALTER TABLE DICTITBL ADD CONSTRAINT PK_DICTITBL PRIMARY KEY (ID);
ALTER TABLE MAINTABLE ADD CONSTRAINT PK_MAINTABLE PRIMARY KEY (ID);
CREATE INDEX X_DICTI_PARENT ON DICTITBL (PARENTID);
CREATE INDEX X_DICTI_VALUE ON DICTITBL (STRVALUE);
COMMIT WORK;
для всех трех слов
select m.NAME from dictitbl d1 left join dictitbl d2 on d2.parentid = d1.parentid
left join dictitbl d3 on d3.parentid = d1.parentid
left join maintable m on m.id = d1.parentid
where d1.strvalue like "РУСС%"
and d2.strvalue like "ПРОМ%"
and d3.strvalue like "КОМП%"
для двух
select m.NAME from dictitbl d1 left join dictitbl d2 on d2.parentid = d1.parentid
left join maintable m on m.id = d1.parentid
where d1.strvalue like "РУСС%"
and d2.strvalue like "КОМП%"
На 60000 записей в главной таблице и 60000 * 5 в словаре работает мгновенно.
Как унифицировать для произвольного числа слов в введенной пользователем строке - твоя работа. У меня это сделано но во-первых сделано в рамках коммерческой разработки и публиковать код я конечно не могу во вторых это уже материал на несколько статей для чего ни времени ни желания ни таланта нет. Но вобщем если подумать реализовать несложно.
← →
Anatoly Podgoretsky © (2004-08-18 14:06) [31]Совпадение может быть полное, по всем словам или не полное по отдельным словам, именно так и строят поиск поисковые машины, для первого используется AND для второго OR
← →
Sergey_Masloff (2004-08-18 14:12) [32]Да конечно мой вариант когда надо искать ВСЕ слова введенные пользователем.
← →
Sergey13 © (2004-08-18 14:17) [33]2galexis ©
Для попробовать/пошаманить. Сделай доп. поле (80 символов), туда скопируй часть исходного поля (начало). Проиндексируй. Стандартно искать по нему. Если поиск не удовлетворил, то по старой схеме с предупреждением, что "Сами понимаете, на ждать". И плюс [3] для нерадивых.
← →
WondeRu © (2004-08-18 14:37) [34]galexis © (18.08.04 11:27)
вырубают ее по ctrl+alt+del
отруби ctrl+alt+del! ;-)
← →
galexis © (2004-08-18 15:18) [35]Со словарями все ясно. А с чего начать создание Thread? Где бы подробнее почитать с примерами. Подскажите пожалуйста.
Страницы: 1 вся ветка
Текущий архив: 2004.09.12;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.025 c