Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
Есть 10млн записей, скажем свойств товара.
Таблица такая:
TB(id int IDENTITY(1,1) NOT NULL, tovid int, groupid smallint, option_name varchar(255), option_value varchar(255), partno tinyint ) 
alter table tb add constraint [abnmcsdf] default ((0)) for [partno]
Нужно разделить датасет, к примеру, по 400 000 тысяч (то есть на 25 частей).
При этом нужно добиться того, чтобы в товары с одинаковым groupid были строго в одной части. То есть, скажем, если в
SELECT * FROM TB order by groupid
записей с groupid=1 составляет 400 100, то ровно это количество должно составить первую часть, тогда как остальные вторая часть будет состоять из groupid=2 и groupid=3 и groupid=4 в том случае, если общее количество groupid in (2,3,4) не больше 400 000, если больше, то только (2,3), если все равно больше, то только (2).

Опять же, два пути - либо выгружать во временную таблицу и работать с ней, либо использовать update top (x) set partno=... в зависимости от предыдущего шага определения количества для конкретной части...
13 май 13, 18:34    [14289258]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
сорри. таблица такая, а то не совсем будет ясно зачем я про временную заговорил.

TB(id int IDENTITY(1,1) NOT NULL, aid int, tovid int, groupid smallint, option_name varchar(255), option_value varchar(255), partno tinyint ) 
alter table tb add constraint [abnmcsdf] default ((0)) for [partno]

Колонка aid отвечает за "условно" партию. То есть в таблице лежит все партиями поставки. Соответственно разные партии поставки по неск млн записей. Поэтому "накипает" со временем и в таблице уже 20,50,100,500 млн записей.
13 май 13, 18:38    [14289265]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
перечитал 5 раз и нифига не понял
что еще за датасет? какое-то хранилище в памяти реализованное на C# и внедренное в БД в виде сборки?
13 май 13, 18:50    [14289288]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
Паганель
перечитал 5 раз и нифига не понял
что еще за датасет? какое-то хранилище в памяти реализованное на C# и внедренное в БД в виде сборки?

Ну выборка из базы. Никакого внедренного хранилища. Все просто и обычно.
10 млн записей, которые выбираются по aid из таблицы - их надо разделить на 25 частей, сохраняя "целостность" по groupid, то есть чтобы в двух разных частях не оказался один и тот же groupid, а консолидировался только в одной части, вне зависимости от количества. Если же речь о двух и более частей, то их общее количество не должно превышать 400 000.
13 май 13, 18:56    [14289301]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
и часто Вы выбираете по 10 млн записей?
13 май 13, 18:58    [14289310]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
Паганель
и часто Вы выбираете по 10 млн записей?

Не часто, но приходится.
13 май 13, 19:04    [14289323]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
я бы подумал над тем как этого избежать
например, какая-то подготовка суммарных данных по ночам...
13 май 13, 19:06    [14289334]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
Паганель
я бы подумал над тем как этого избежать
например, какая-то подготовка суммарных данных по ночам...

Поверьте, я бы тоже подумал, если бы в этом состояла задача.
Но задача в другом - разбить данные на части.

Выше мне удалось более четко разъяснить задачу?
13 май 13, 19:08    [14289336]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31959
_Промешан_,

А какой у вас вопрос?
Как разделить данные на нужные части, или как потом с ними работать (куда то сохранять, добавить признак в таблицу)?
13 май 13, 19:11    [14289339]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
alexeyvg
_Промешан_,

А какой у вас вопрос?
Как разделить данные на нужные части, или как потом с ними работать (куда то сохранять, добавить признак в таблицу)?

Сначала разделить. Как-нибудь извращнуться в хранимке в общем. Наверное не без курсоров (ну зато хоть крутилку пользователю показать можно будет).

partno - по сути тот признак, о котором вы испрашиваете.
13 май 13, 19:14    [14289352]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
alexeyvg
_Промешан_,

А какой у вас вопрос?
Как разделить данные на нужные части, или как потом с ними работать (куда то сохранять, добавить признак в таблицу)?

В общем если углубиться в детали...

10 млн пользователю для обработки не нужно и вздорно. Но он так или иначе не обрабатывает все 10млн и не видит 10млн записей. Суть в другом - по мере того, как пльзователь работает с конкретным aid (поставкой), происходят многочисленные операции выборки и агрегирования над всей "поставкой". Это позволяет "умереть процессу" на определенном этапе. Поэтому есть необходимость разбить на части. На 25 частей, на 50, 100 и так далее. На более мелком датасете все "летает" и по мере возможности пользователь обрабатывает данные (это происходит, разумеется не за один рабочий день, но это ок).
13 май 13, 19:19    [14289360]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
И разбить надо в соответствии с правилами выше. То есть чтобы товары одной группы находились всегда в пределах одной части, то есть нефрагментированными вне зависимости от того, какое выбрано количество частей, однако при этом два и более товарных группы могли размещаться в одной части, если их сумма не превышает заданной, но и не должна быть более заданной.
13 май 13, 19:22    [14289365]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
Glory
Member

Откуда:
Сообщений: 104751
_Промешан_
Поэтому есть необходимость разбить на части. На 25 частей, на 50, 100 и так далее. На более мелком датасете все "летает" и по мере возможности пользователь обрабатывает данные (это происходит, разумеется не за один рабочий день, но это ок).

Это называется paging.
13 май 13, 19:36    [14289389]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
Glory
_Промешан_
Поэтому есть необходимость разбить на части. На 25 частей, на 50, 100 и так далее. На более мелком датасете все "летает" и по мере возможности пользователь обрабатывает данные (это происходит, разумеется не за один рабочий день, но это ок).

Это называется paging.
Это мне понятно в терминах веб.
У меня же не веб.
Но как назвать, кажется не решает задачу ))
14 май 13, 12:16    [14291826]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
Glory
Member

Откуда:
Сообщений: 104751
_Промешан_
Это мне понятно в терминах веб.
У меня же не веб.

paging - он везде paging
14 май 13, 12:18    [14291845]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
_Промешан_,

версия сервера какая?
PRINT @@VERSION
14 май 13, 12:25    [14291882]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
iap
_Промешан_,

версия сервера какая?
PRINT @@VERSION
Забываю частенько..

Microsoft SQL Server 2008 (SP3) - 10.0.5500.0 (X64) 
Sep 21 2011 22:45:45
Copyright (c) 1988-2008 Microsoft Corporation
Standard Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
14 май 13, 14:16    [14292837]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
Glory
_Промешан_
Это мне понятно в терминах веб.
У меня же не веб.

paging - он везде paging
Ну как скажешь. Мне не как назвать, а как сделать бы...
14 май 13, 14:17    [14292853]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
Glory
Member

Откуда:
Сообщений: 104751
_Промешан_
Мне не как назвать, а как сделать бы...

Взять и написать код ? Не пробовали ? По заданному вами "И разбить надо в соответствии с правилами выше."
14 май 13, 14:19    [14292884]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
Glory
_Промешан_
Мне не как назвать, а как сделать бы...

Взять и написать код ? Не пробовали ? По заданному вами "И разбить надо в соответствии с правилами выше."
Пробовал. Вы слишком плохо обо мне думаете. И слишком хорошо о себе
14 май 13, 14:24    [14292930]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
Glory
Member

Откуда:
Сообщений: 104751
_Промешан_
Пробовал.

И что не получилось ?
14 май 13, 14:24    [14292944]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
Glory
_Промешан_
Пробовал.

И что не получилось ?

Не получился оптимальный вариант.
14 май 13, 14:25    [14292953]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
В общем вылезло что-то вроде этого:
Во временную таблицу
#tgcnt
выливаю аггрегированное количество сгруппированное по groupid и сортированное пол количеству ASC. Затем последовательным сложением сортированного списка по количеству товаров в группе, выясняю, выходит ли за заданные границы сумма, если выходит и в текущей части более одного тгид, то проставляется top(@i) текущий partno.

Другое дело, я не вполне уверен, будет ли соответствовать
update top(@id)
сортированному списку
order by cnt
?????

    create table #tgcnt (groupid smallint,cnt int,partno smallint null)     
    
    declare @cnt int, @act int = 400, @sum int=0,@tgids smallint=0,@i smallint=0
    set @cnt = @act * 1000  -- @act = 10, 25, 50, 100, 250, 500, 1000 
    while exists(select 1 from #tgcnt where partno is null)
    begin
      set @sum = 0
      set @tgids = 0
      set @i = 0
      while (@sum < @cnt)
      begin
        set @i = @i + 1
        set @sum = (select sum(a.cnt) from (select top(@i) cnt from #tgcnt where partno is null order by cnt,tgid) a)
        raiserror ('%d   %d',1,1, @i,@sum) with nowait
      end
      if @i != 1 and @sum != @cnt set @i = @i - 1
      update top(@i) #tgcnt set partno=isnull((select max(partno) from #tgcnt),0)+1 where partno is null
    end
14 май 13, 14:57    [14293224]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31959
_Промешан_
Glory
пропущено...

И что не получилось ?

Не получился оптимальный вариант.
А какой получился, что же вы не выкладываете?

И пример с данными давайте.

declare @t table (id int, g int)
insert @t values
(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),
(11,2),(12,2),(13,2),(14,2),(15,2),
(21,3),(22,3),(23,3),(24,3),(25,3),(26,3),(27,3),(28,3),(29,3)

;with tt as (
	select g, count(*) as n
	from @t
	group by g
), ttt as (
select t1.g, SUM(t2.n) n
from tt t1
	join tt t2 on t2.g <= t1.g
group by t1.g
)
select t1.*, t2.n, t2.n / 5
from @t t1
	join ttt t2 on t2.g = t1.g
where t2.n / 5 = 2
14 май 13, 14:58    [14293227]     Ответить | Цитировать Сообщить модератору
 Re: Если нужно разделить данные на части, то какой путь выбрать?  [new]
_Промешан_
Member

Откуда:
Сообщений: 970
alexeyvg,

выложил выше, смотрите.

А ваш пример просто бьет на 5 частей?
14 май 13, 15:01    [14293251]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить