Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Оптимизация поиска. / 7 сообщений из 7, страница 1 из 1
26.06.2006, 12:13
    #33814235
moteus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация поиска.
Здравствуйте!
ASA 9.0.2.3044

Необходимо реализовать поиск по принципу:
На входе имеем телефонный номер (напр. 749512345) и № группы;
В базе храняться для каждой группы полный набор префиксов (напр. 7;74;7495)
Соответственно выбрать необходимо выбрать префикс "7495", т.к. с него начинаеться пришедший номер и он имеет максимальную длинну.
Т.е. запрос
Select first p."ID"
from "Prefixes" as p
where (p."GroupID"=vGroup) and (vNumber like p."Prefix"||'%')
order by p."PrefixLen" desc
Возвращает правельный результат.
Проблема в том что поиск происходит не по индексу, а одной группе принадлежит порядка 11 тыс. префиксов.Количество групп порядка 50.

Т.к. более 99% префиксов имеют длинну не более 9 цифр и не имеют ведущих нулей, то их можно представить в виде чисел и производить поиск в цикле в ХП начиная с длинны 9. Поиск будет происходить по уникальному индексу состоящему из 2 полей типа INTEGER.
Для реализации этого механизма необходимо также обеспечить поиск по префиксам которые не возможно преобразовать в integer (например содержащие ведущие 0, не цифровые символы или длинною более 9 сиволов). Таких префиксов будет не более 100 на группу, поэтому мне кажется целесообразно их разделить физически на 2 таблици и поиск производить по приведенному выше запросу в маленькой таблице, после чего уже производить поиск по основной таблице.
Пока сделал вычисляемое поле integer в тойже таблице куда пишеться либо число соответствующее префиксу либо NULL. И если бы была возможность физически разделить данные в рамках одной таблици по этому принципу то можно было бы обойтись и без 2 таблиц.
В связи с этим возникло сразу несколько вопровов

1)Стоит ли вообще разбивать на 2 таблицы.
И если стоит, то
2)Возможно ли сделать обновляемое представление, для того чтобы не переписывать клиентов (для просмотра и редактирования справочников префиксов).
3)Как лучше организовать ограничения целостности на подчененных таблицах. Понятно что на FK такого сделать не получиться и надо использовать тригеры, а для PK префиксов разделить регионы для разных таблиц (или использовать глобальный инкоемент)

Ну и конечно интересуют критика и другие предложения.
...
Рейтинг: 0 / 0
26.06.2006, 12:30
    #33814280
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация поиска.
moteusЗдравствуйте!
ASA 9.0.2.3044

Необходимо реализовать поиск по принципу:
На входе имеем телефонный номер (напр. 749512345) и № группы;

Ну и конечно интересуют критика и другие предложения.Используй знания, полученные в школе. Ограничь область поиска. В школе не решали задачи о попадании точки в круг, заданный на координатной плоскости? ТАм вначале отбирались те точки, что попадали в квадрат с длиной стороны = диаметру окружности и центром в точке центра окружности, а уж затем выполнялись дополнительные проверки на попадание именно в круг. И будет тебе счастье.
Перепиши условие
Код: plaintext
where  (p."GroupID"=vGroup) and (vNumber like p."Prefix"||'%')
В виде
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
where  (p."GroupID"=vGroup) 
  and p."Prefix" between substr(vNumber, 1 , 1 )  and vNumber 
-- То есть берем только те префиксы, чо попадают между первым символом номера и самим номером,
-- тем самым ограничив круг поиска.
-- Аналог функции SUBSTR сам подбери, я WatcomSQL не знаю  
and (vNumber like p."Prefix"||'%')
-- А это уже дополнительные условия отбора записей
...
Рейтинг: 0 / 0
26.06.2006, 13:01
    #33814380
old_joy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация поиска.
авторALTER TRIGGER "code_mg" .code_mg before insert order 1 on
DBA.tarif
referencing new as new_name
for each row
begin
declare i smallint;
declare my_kod char(6);
//Определяем максимально длинный код
set i=6;
//Минимальная длина кода - 2 цифры
while i >= 2 loop
//Выделяем возможный код
set my_kod=substr(new_name.nomer_nab,2,i);
//Проверяем существование такого кода
if exists(select* from DBA.tarif_kod_napr where
kod_napr = my_kod) then
set new_name.kod_napr=my_kod;
set new_name.nomer_nab=substr(new_name.nomer_nab,i+2);
//Признак найденного кода
set i=1
end if;
set i=i-1
end loop;
//Если цикл прошел полностью и код не найден, то i=1, если найден, i=0
if i = 1 then
//Вставляем строку в протокол
insert into DBA.tarif_prot(my_comment,n_pp_input) values('Такого кода нет',
new_name.n_pp)
end if
end
...
Рейтинг: 0 / 0
26.06.2006, 20:15
    #33815467
moteus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация поиска.
В общем я остановился на решении с одной таблицей и вычисляемым полем типа unsigned integer.
Сначала ищеться по условию
Код: plaintext
"Group"=vGroup and PrefixInt is null vNumber like "Prefix" || '%' 
а дальше в цикле начиная с 9 знаков
Код: plaintext
"Group"=vGroup and PrefixInt = vIntNumber 

Этот вариант оказалься достаточно быстрым и не требует переделки базы и клиента.
Поле PrefixInt я сделал вычисляемым
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
if(
  (isnumeric(Prefix) =  1 ) and
  (length(Prefix) <  10 ) and
  (substr(Prefix, 1 , 1 ) !=  0 )
) then
   cast(Prefix_IN as unsigned integer)
else
   NULL
endif
old_joy
твое решение мне не подходит т.к. из 11 тыс. префиксов может оказаться 2 с длинной порядка 10-15.

Спасибо всем откликнувшимся.
...
Рейтинг: 0 / 0
27.06.2006, 06:00
    #33815722
old_joy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация поиска.
Это что же у вас за станция? На Меридиане только 16 цифр набора выдает...
...
Рейтинг: 0 / 0
27.06.2006, 10:21
    #33816000
moteus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация поиска.
old_joyЭто что же у вас за станция?
Так я и говорю что из 11 тыс. может окасаться около 100 номеров длиннее 9 символов (например отдельные номера), или например могут подовать не чистый Е164 а в начале могут присобачить и еще какойнибудь префикс например '12345#7495123456' и надо будет искать '12345#74951'. Но т.к. такие ситуации подподают под исключения то оптимизировать все же стоит именно поиск префиксов E164 длинной до 9 цифр.
...
Рейтинг: 0 / 0
28.06.2006, 05:31
    #33818128
old_joy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация поиска.
Понятно.
У меня весь мусор держится сутки в оперативной базе. Собственно расчет идет в ночь при переписывании в базу постоянного хранения, перед этим всякую ерунду из наборов стираю, потому мне 6 первых символов хватает.
...
Рейтинг: 0 / 0
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Оптимизация поиска. / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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