Вопрос о оптимальном алгоритме поиска в БД

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

mogikanin
Сообщения: 20
Зарегистрирован: 20 июн 2007, 13:05

Вопрос о оптимальном алгоритме поиска в БД

Сообщение mogikanin » 20 июн 2007, 13:24

Дельфи, interbase 6.5. Имеется следующая задача: в БД содержатся префиксы телефонных номеров (значащие разряды тел. номеров, поле типа char) и маски (не значащие разряды номеров, пример "****") , вместе они дают шаблон телефонного номера, так же имеется набранный телефонный номер необходимо сопоставить тел. номеру запись с самым похожим на него шаблоном, количество цифр номера и шаблона должно совпадать, телефонных номеров много.
В принципе прога уже написана, но скорость ее работы меня не устраивает, может у вас, уважаемые коллеги, возникнут какие-нибудь светлые идеи по поводу алгоритма поиска данного шаблона.
Свои приводить не буду что бы не сбивать, заранее спасибо.

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Re: Вопрос о оптимальном алгоритме поиска в БД

Сообщение stix-s » 20 июн 2007, 13:34

mogikanin писал(а):Дельфи, interbase 6.5. Имеется следующая задача: в БД содержатся префиксы телефонных номеров (значащие разряды тел. номеров, поле типа char) и маски (не значащие разряды номеров, пример "****") , вместе они дают шаблон телефонного номера, так же имеется набранный телефонный номер необходимо сопоставить тел. номеру запись с самым похожим на него шаблоном, количество цифр номера и шаблона должно совпадать, телефонных номеров много.
В принципе прога уже написана, но скорость ее работы меня не устраивает, может у вас, уважаемые коллеги, возникнут какие-нибудь светлые идеи по поводу алгоритма поиска данного шаблона.
Свои приводить не буду что бы не сбивать, заранее спасибо.
ну, я бы например varchar применял :)

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 20 июн 2007, 13:41

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

mogikanin
Сообщения: 20
Зарегистрирован: 20 июн 2007, 13:05

Сообщение mogikanin » 20 июн 2007, 13:46

to kdv дело в том что префикс короче чем тел. номер т .е. номер набранный допустим 8442454545 а префикс будет например "844245" и маска "****" каким же образом здесь можно использовать LIKE я что то не догоняю, может торможу? :(

mogikanin
Сообщения: 20
Зарегистрирован: 20 июн 2007, 13:05

Сообщение mogikanin » 20 июн 2007, 13:51

to kdv насчет разбиения: можно префиксы выбирать по первой цифре и далее лопатить всю выборку, на предмет поиска самого похожего шаблона, но выборка будет большая обработка идет долго, можно выполнять к БД ряд запросов, постепенно отрезая от номера цифры с хвоста и ищя в базе по полученной строке префиксы которые с учетом маски дадут искомы номер, я так еще не пробовал но мне кажется будет еще дольше.

mogikanin
Сообщения: 20
Зарегистрирован: 20 июн 2007, 13:05

Сообщение mogikanin » 20 июн 2007, 13:52

Блин привел все таки алгоритмы :(

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 20 июн 2007, 14:00

mogikanin писал(а):Блин привел все таки алгоритмы :(
starting with ('телепон') еще существует,
есть мнение, что like('теле%') отработает медленне, чем like('теле___')

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 20 июн 2007, 14:01

перебирать в процедуре через starting with
от длины тел номера(или максимальной длины префикса) до первого символа. и будет найден наиболее совпадающий шаблон префикса, дальше уже считать кол-во звездочек, или вообще изначально лучше отдельно хранить длину шаблона.
И так будет достаточно быстро при наличии индекса по префиксу.

mogikanin
Сообщения: 20
Зарегистрирован: 20 июн 2007, 13:05

Сообщение mogikanin » 20 июн 2007, 14:06

to mdf в хранимой процедуре? или в процедуре самой софтины?

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 20 июн 2007, 14:07

В ХП

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 20 июн 2007, 14:14

mdfv писал(а):перебирать в процедуре через starting with
от длины тел номера(или максимальной длины префикса) до первого символа. и будет найден наиболее совпадающий шаблон префикса, дальше уже считать кол-во звездочек, или вообще изначально лучше отдельно хранить длину шаблона.
И так будет достаточно быстро при наличии индекса по префиксу.
а зачем вообще длина шаблона? определяющим является длина номера телефона
Последний раз редактировалось stix-s 20 июн 2007, 14:16, всего редактировалось 1 раз.

mogikanin
Сообщения: 20
Зарегистрирован: 20 июн 2007, 13:05

Сообщение mogikanin » 20 июн 2007, 14:15

to stix-s
я вообще то не супер спец, но запросы типа

select pref
from table1
where pref starting with (containing, like) "telnum"

не работают если pref в длину меньше telnum в принципе

а наоборот тоже не работает (результат пустой) но это уже видимо особенности Interbase

pref поле таблицы, telnum строка с номером телефона

mogikanin
Сообщения: 20
Зарегистрирован: 20 июн 2007, 13:05

Сообщение mogikanin » 20 июн 2007, 14:19

to mdf попробую счас. Спасиба.
to stix-s длина шаблона должна совпадать с длиной набранного номера

mdfv
Сообщения: 119
Зарегистрирован: 23 май 2006, 15:53

Сообщение mdfv » 20 июн 2007, 14:22

stix-s писал(а): а зачем вообще длина шаблона? определяющим является длина номера телефона
...которая и сравнивается с длиной шаблона(который может иметь разную длину, для разных станций и способов формирования номера),
и если сразу не совпадает, то и искать нечего.

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 20 июн 2007, 14:33

mogikanin писал(а):to stix-s
я вообще то не супер спец, но запросы типа

select pref
from table1
where pref starting with (containing, like) "telnum"

не работают если pref в длину меньше telnum в принципе

а наоборот тоже не работает (результат пустой) но это уже видимо особенности Interbase

pref поле таблицы, telnum строка с номером телефона
Наоборот, это как?
select * from prefixes px
where px.prefix starting with ('8346') - прекрасно работает :)
и даже так работает
select * from prefixes px
where '8346' starting with (px.prefix)
Последний раз редактировалось stix-s 20 июн 2007, 14:43, всего редактировалось 1 раз.

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 20 июн 2007, 14:35

mdfv писал(а):
stix-s писал(а): а зачем вообще длина шаблона? определяющим является длина номера телефона
...которая и сравнивается с длиной шаблона(который может иметь разную длину, для разных станций и способов формирования номера),
и если сразу не совпадает, то и искать нечего.
стоп, длина номера стандартна - 10 символов и никак иначе
МГ - 8телепон(с кодом города)
МН - 810 код страны телепон
если телефон записывать абы как, тогда о каких префиксах можно речь весть?
с какого боку мне нужна тут длина шаблона?

mogikanin
Сообщения: 20
Зарегистрирован: 20 июн 2007, 13:05

Сообщение mogikanin » 20 июн 2007, 14:40

to stix-s номер получаем в виде например "8442454545" префикс в БД для такого номера будет в длину меньше либо равен 10 знакам т.е. длине этого самого тел. номера, равен он в длину этому номеру только в эстраординарных случаях, а чаще всего он короче например префикс может быть "844245" при таком раскладе конструкции с LIKE, Starting with и Containing не работают, к сожалению.

mogikanin
Сообщения: 20
Зарегистрирован: 20 июн 2007, 13:05

Сообщение mogikanin » 20 июн 2007, 14:44

to stix-s у каждой АТС свои правила набора тел. номеров, номера имеют стандартный тип только в том случае если звонки с этих номеров идут через телефонные сети общего пользования, если же вызов идет не через сети ТФОП то номера могут быть и не стандартными, единственное условие - они должны быть уникальными для этой АТС

mogikanin
Сообщения: 20
Зарегистрирован: 20 июн 2007, 13:05

Сообщение mogikanin » 20 июн 2007, 14:45

но к делу это отношения не имеет

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 20 июн 2007, 14:46

mogikanin писал(а):to stix-s номер получаем в виде например "8442454545" префикс в БД для такого номера будет в длину меньше либо равен 10 знакам т.е. длине этого самого тел. номера, равен он в длину этому номеру только в эстраординарных случаях, а чаще всего он короче например префикс может быть "844245" при таком раскладе конструкции с LIKE, Starting with и Containing не работают, к сожалению.
уверен?
select * from prefixes px
where '83466343126' starting with (px.prefix) - отрабатывает на ура, находит нужный мне префикс, проблема будет, если их будет несколько разной длины 834, 8346, 83466

Ответить