Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите с запросом / 15 сообщений из 15, страница 1 из 1
10.02.2019, 12:28
    #39771772
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Всем добрый день.

Выполняю обработку списка телефонных номеров на стороне клиентского c# приложения. Задача в том, чтобы определить для каждого номера телефона, к какому региону\городу он принадлежит. В базе данных хранится информация по сопоставлению всех кодов телефонов по всем операторам связи с регионами\городами в формате, представленном ниже. Записей в этой таблице сопоставления 23 000. За 1 раз осуществляется обработка порядка 3 000 телефонных номеров в 100 параллельных потоков, задача регулярная, и поэтому важна производительность решения.
Помогите, пожалуйста, сделать оптимальный запрос на быстрое получение данных из таблицы сопоставления по 1 номеру телефона. Например, как можно получить из таблицы сопоставления код региона для номеров телефонов: 89994911546 и 89825594623?

Пример данных таблицы сопоставления "код телефона-регион"
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
create table t_REG_TelCodes
(
	tl_id int identity(1,1) primary key,
	i_id_region int,
	tl_code nvarchar(11)
)
insert into t_REG_TelCodes(i_id_region, tl_code) select 1, '9994911xxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 1, '9994912xxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 1, '9994913xxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 2, '9994919xxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 2, '9994920xxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 3, '98302xxxxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 3, '983030xxxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 3, '983031xxxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 3, '983032xxxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 4, '983050xxxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 5, '983051xxxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 6, '983052xxxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 7, '9825xxxxxx'
insert into t_REG_TelCodes(i_id_region, tl_code) select 8, '9826xxxxxx'
...
Рейтинг: 0 / 0
10.02.2019, 12:40
    #39771779
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
1. Убрать из '9994911xxx' xxx. Чай не порносайт.
2.
Код: sql
1.
2.
Select t.[телефонный номер], r.i_id_region
  from [порядка 3 000 телефонных номеров] as t inner join t_REG_TelCodes as r on t.[телефонный номер]  like tl_code + '%'


3. Нахера тут "100 параллельных потоков"?
...
Рейтинг: 0 / 0
10.02.2019, 12:44
    #39771783
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Ах да,

4. 89994911546 и 89825594623 приводите к 9994911546 и 9825594623.
5. Либо, что правильнее, в таблицу регионов добавьте 8. Вдруг Куала-Лумпур надо будет обрабатывать?
6. Но есть ишо +7. Значит в таблицу регионов надо добавить записи с +7.
...
Рейтинг: 0 / 0
10.02.2019, 12:47
    #39771785
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
aleks222,

Данные по [порядка 3 000 телефонных номеров] хранятся не в бд, а в оперативной памяти клиентского приложения. Телефонные номера собираются из различных источников данных в 100 параллельных потоках, задача в том, чтобы сразу после получения номера определить его принадлежность к региону. Можно, кончено, сначала собрать все телефоны, потом вставить их в какую-либо таблицу в БД и выполнить предложенный вами запрос, но данные по [порядка 3 000 телефонных номеров] не требуется хранить в БД, они временные.
...
Рейтинг: 0 / 0
10.02.2019, 12:49
    #39771787
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
aleks222,

Да, не учел это в примере данных. Все номера телефонов начинаются с "8", и в таблице сопоставления и в [порядка 3 000 телефонных номеров]
...
Рейтинг: 0 / 0
10.02.2019, 12:51
    #39771788
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Vsevolod Valeks222,

Данные по [порядка 3 000 телефонных номеров] хранятся не в бд, а в оперативной памяти клиентского приложения. Телефонные номера собираются из различных источников данных в 100 параллельных потоках, задача в том, чтобы сразу после получения номера определить его принадлежность к региону. Можно, кончено, сначала собрать все телефоны, потом вставить их в какую-либо таблицу в БД и выполнить предложенный вами запрос, но данные по [порядка 3 000 телефонных номеров] не требуется хранить в БД, они временные.

Боюсь показаться банальным, но с вашим уровнем программирования быстрее ВСТАВИТЬ номера в таблицу #temporal и выполнить запрос. Можно, даже, по одному.
...
Рейтинг: 0 / 0
10.02.2019, 12:57
    #39771790
Vsevolod V
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Спасибо)
...
Рейтинг: 0 / 0
10.02.2019, 16:04
    #39771851
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Vsevolod V,

Найти один раз регионы для 3000 номеров гораздо оптимальнее, чем 3000 раз искать по одному.
Для этого
1. Уберите из значений префиксов "ххх..."
2. Создайте индекс create index ... on t_REG_TelCodes (tl_code) include (i_id_region)
3. Процедура поиска
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
create procedure p_GetPhonesWithRegion
 @tl_list xml

as
begin
 set nocount on;
 
 with s(phone_number) as
 (
  select
   t.n.value('@number', 'nvarchar(100)')
  from
   @tl_list.nodes('/phone') t(n)
 )
 select
  s.phone_number, r.i_id_region
 from
  s outer apply
  (select top (1) i_id_region from dbo.t_REG_TelCodes where s.phone_number >= tl_code and s.phone_number like tl_code + N'%' order by tl_code desc) r;

end;

4. На клиенте формируйте список номеров в виде '<phone number = "89830514567" /><phone number = "89830524567" /><phone number = "8982511111" />' и передавайте при вызове процедуры.
...
Рейтинг: 0 / 0
10.02.2019, 16:13
    #39771853
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
invmVsevolod V,

Найти один раз регионы для 3000 номеров гораздо оптимальнее, чем 3000 раз искать по одному.
Для этого
1. Уберите из значений префиксов "ххх..."
2. Создайте индекс create index ... on t_REG_TelCodes (tl_code) include (i_id_region)
3. Процедура поиска
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
create procedure p_GetPhonesWithRegion
 @tl_list xml

as
begin
 set nocount on;
 
 with s(phone_number) as
 (
  select
   t.n.value('@number', 'nvarchar(100)')
  from
   @tl_list.nodes('/phone') t(n)
 )
 select
  s.phone_number, r.i_id_region
 from
  s outer apply
  (select top (1) i_id_region from dbo.t_REG_TelCodes where s.phone_number >= tl_code and s.phone_number like tl_code + N'%' order by tl_code desc) r;

end;

4. На клиенте формируйте список номеров в виде '<phone number = "89830514567" /><phone number = "89830524567" /><phone number = "8982511111" />' и передавайте при вызове процедуры.

Зачем этот бред?
Bulk Insert нонича вполне доступен в C#.
...
Рейтинг: 0 / 0
10.02.2019, 18:27
    #39771893
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
aleks222Зачем этот бред?
Bulk Insert нонича вполне доступен в C#.Не пробовал задать себе вопрос: "Нахрена провоцировать запись в ЖТ, когда можно этого не делать?"
...
Рейтинг: 0 / 0
11.02.2019, 05:50
    #39771979
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
invmaleks222Зачем этот бред?
Bulk Insert нонича вполне доступен в C#.Не пробовал задать себе вопрос: "Нахрена провоцировать запись в ЖТ, когда можно этого не делать?"
Так он для этого и предназначен?
...
Рейтинг: 0 / 0
11.02.2019, 10:35
    #39772053
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
aleks222Так он для этого и предназначен?Ну, дарагуля, банки тоже предназначены для выдачи кредитов. Однако, ты же не берешь кредит, когда можно его не брать?
Или таки берешь?
...
Рейтинг: 0 / 0
11.02.2019, 11:41
    #39772098
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Vsevolod V,

Парень, так тебе не помочь, от тебя надо структуру таблиц и запросы что ты выполняешь.

ДА и тут надо , я думаю, постановку задачи или архитектуру менять.
Поэтому надо техзадание.
Ты же написал только какую=то лабуду в вопросе.
В общем... без шансов почти тебе помочь.

23 тыщи записей сопоставлений вообще можно в клиента БД всосать на старте и далее уже там искать что надо.
100 параллельных потоков там 100% не нужно, нигде нет такого высокого уровня параллелизма, это не повысит производительность.
...
Рейтинг: 0 / 0
11.02.2019, 13:29
    #39772200
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Vsevolod V,

уберите кресты и в цикле лайком определяйте от самых длинных к самым коротким. Цикл по длине номера шаблона. Максимум за 9 проходов разберете все номера. Способ достаточно эффективный. На кой вам 100 потоков, реалтайм, что ли?
...
Рейтинг: 0 / 0
13.02.2019, 12:07
    #39773265
=Сергей=
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Вам нужно сделать справочник префиксов (DEF-кодов):
Код: sql
1.
create table [T_DEF]([id] int identity(1,1),[Prefix] varchar(20) not null,[Region] nvarchar(100) not null)


заполнить его правильными префиксами, например взять с rossvyaz.ru
Сделать функцию определения региона по префиксу, типа:
Код: sql
1.
2.
3.
4.
5.
create function [dbo].[fn_GetRegion]( @Number varchar(20)) rerurns nvarchar(100)
as
begin
//простая логика
end


После чего будет вам счастье:
Код: plsql
1.
2.
3.
4.
5.
6.
declare @Numbers table ([Number] varchar(20))
insert into @Numbers values ('798553223413564','74561233489153','45621681324324351')
select
*
from @Numbers A
outer apply [dbo].[fn_GetRegion](A.[Number]) B


Это будет значительно быстрее, чем обрабатывать данные в софте на C#.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите с запросом / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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