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

Откуда: Прага
Сообщений: 776
С вашего разрешения задам свой вопрос:
Есть таблицы вида T_IVF_2015_001, где 2015 - номер года, 001 - номер продукта. Туда заливаются данные о реализованных продуктах по годам. В среднем в каждой таблице продукта 001 по 100М записей, у остальных 10 продуктов в сумме 5М. Заливает данные кривая прога из логов кассовых аппаратов, и посему случаются повторения, и от них окончательно незьзя избавиться - глюки счётной машинки, когда вместо 1 записи вставит 2,3,4 одинаковые; ошибки маркировки; воровство и подделки - дублирующихся записей сейчас примерно 3%, их колличество можно снизить, но избавиться окончательно нельзя. Поэтому на таблицах НЕТ первичного ключа, есть только кластерный индекс по номеру изделия и обычный индекс по номеру партии. Она собственно и нужна чтобы выяснить номер партии, по которой прошёл продукт, других полезных данных там нет.

Для отчётов нужно, к примеру, найти всех, кто получил продукцию выпущенную Васей с января по март 2015 года.
Беру номера изделий, которые делал Вася и хочу найти в этих таблицах партии, куда попала это продукция. Ну и всё, на этом прогресс заканчивается, всё очень долго.
Простой
select count(*) T_IVF_2015_001
выполняется больше минуты.

Это всё можно переделать, перезалить (есть исходные текстовые данные) или реорганизовать но не понятно, как работать с такими объёмами данных? Посоветуйте что-нибудь для вдохновения. Данные в таблицы заливаются 1 раз в день, пачками по 500000+ в обороте продукция за 2 года (2015 и 2016, остальное уже не изменяется), основные запросы на чтение.

select @@version

Microsoft SQL Server 2008 R2 (RTM) - 10.50.1617.0 (X64) Apr 22 2011 19:23:43 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)
19 янв 16, 20:13    [18703088]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
Glory
Member

Откуда:
Сообщений: 104760
Шыфл
но избавиться окончательно нельзя.

Избавиться от дублей в таблице _можно_
Достаточно просто их не добавлять в таблицу

Шыфл
но не понятно, как работать с такими объёмами данных?

Вы про select count(*) T_IVF_2015_001 что ли ?

Сообщение было отредактировано: 19 янв 16, 20:18
19 янв 16, 20:17    [18703102]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
Шыфл
Member

Откуда: Прага
Сообщений: 776
Glory
Шыфл
но избавиться окончательно нельзя.

Избавиться от дублей в таблице _можно_
Достаточно просто их не добавлять в таблицу

Да, я тоже подумал про таблицу исключений... Это первый очевидный шаг, если структуру сильно не менять. Но всё равно, при существующей архитектуре извлечение данных - курсор и маразм по всем таблицам
+

        SET @sql_command = N''
        SET @sql_command = @sql_command + N'INSERT #T_IVF' + ' '
        SET @sql_command = @sql_command + N'SELECT IVF.vou_number, IVF.vou_fv, IVF.vrf_batch_id' + ' '
        SET @sql_command = @sql_command + N'FROM ' + (@db_name + @table_name) + ' IVF' + ' '
        SET @sql_command = @sql_command + N'JOIN reimbursement.dbo.T_VRF_voucher_redemption_form VRF' + ' '
        SET @sql_command = @sql_command + N'ON VRF.vrf_batch_id = IVF.vrf_batch_id' + ' '
        SET @sql_command = @sql_command + N'WHERE vou_number BETWEEN @first_vou_number AND @last_vou_number' + ' '
        SET @sql_command = @sql_command + N'AND ((@date_from IS NULL) OR (@date_from <= VRF.vrf_send_date))' + ' '
        SET @sql_command = @sql_command + N'AND ((@date_to IS NULL) OR (@date_to >= VRF.vrf_send_date))'


Glory
Шыфл
но не понятно, как работать с такими объёмами данных?

Вы про select count(*) from T_IVF_2015_001 что ли ?

Каждая таблица продукта 001 по 10Гб, и любой запрос, как говорится, ждите ответа в следующей серии...
19 янв 16, 20:27    [18703132]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
Glory
Member

Откуда:
Сообщений: 104760
Шыфл
Но всё равно, при существующей архитектуре извлечение данных - курсор и маразм по всем таблицам

какой курсор ? какие таблицы исключений ?
Добавление данных НЕ должно добавлять дубликаты

Шыфл
Каждая таблица продукта 001 по 10Гб, и любой запрос, как говорится, ждите ответа в следующей серии...

Вы ждете волшебную команду, которая сама переберет все таблицы по маске ?
Нжуно было сразу делать одну таблицу
19 янв 16, 20:32    [18703141]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
DECLARE @t TABLE
(
    val INT PRIMARY KEY WITH(IGNORE_DUP_KEY=ON)
)

INSERT INTO @t (val)
VALUES (1), (1)

SELECT * FROM @t


Если данные у Вас вставляются по одному или небольшими пакетами, то можно IGNORE_DUP_KEY использовать.
Так на этапе вставки бы будете игнорировать дубликаты.

По поводу того как COUNT-ом пользоваться уже столько все говорили, что проще погуглить...

Если лень, то вот линк - http://habrahabr.ru/post/271797/
19 янв 16, 21:31    [18703296]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
aleks2
Guest
1. Ну, про IGNORE_DUP_KEY уже сказали.
2. При наличии уникального кластерного индекса "по номеру изделия"
select * from T_IVF_2015_001 as t inner join @ВасиныИзделия as v on v.[номер изделия] = t.[номер изделия]
не может выполняться дольше
Шыфл
Простой
select count(*) T_IVF_2015_001
выполняется больше минуты.

3. Да и то, если вася сделал всё изделия.
20 янв 16, 07:06    [18703918]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
Шыфл
Member

Откуда: Прага
Сообщений: 776
Glory
Шыфл
Но всё равно, при существующей архитектуре извлечение данных - курсор и маразм по всем таблицам

какие таблицы исключений ?
Добавление данных НЕ должно добавлять дубликаты

А куда их девать, по вашему? Если не отлавливать дупликаты, кассир легко их проведёт по кассе, и нагреет себе руки, а в случае чего всё спишет на баг программы. Наличие дупликатов это часть логики процесса, для контроля над ними, можно сказать, всё и делается.

Glory
Шыфл
Каждая таблица продукта 001 по 10Гб, и любой запрос, как говорится, ждите ответа в следующей серии...

Вы ждете волшебную команду, которая сама переберет все таблицы по маске ?
Нужно было сразу делать одну таблицу

Ну, как бэ не знаю. Тут у нас самопальное партиционирование, так сказать. Если нужен продукт 010, он работает только с нужными таблицами, в которых 100к записей, а не 100М. В историю, опять же, можно далеко не лезть, если не нужно

Если сделать 1 таблицу, даже для каждого продукта свою, то продукт 001 будет монстром с миллиардом записей. Там, чувствую, даже select top 1 будет тормозить больше минуты ;)) Или нет?
20 янв 16, 11:43    [18704893]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
Glory
Member

Откуда:
Сообщений: 104760
Шыфл
А куда их девать, по вашему? Если не отлавливать дупликаты, кассир легко их проведёт по кассе, и нагреет себе руки, а в случае чего всё спишет на баг программы. Наличие дупликатов это часть логики процесса, для контроля над ними, можно сказать, всё и делается.

Если кассир совершает 2,3,4 операции, то это не дубликаты.

Шыфл
Если сделать 1 таблицу, даже для каждого продукта свою, то продукт 001 будет монстром с миллиардом записей.

А вы про несамопальное партицирование слышали ?

Шыфл
Там, чувствую, даже select top 1 будет тормозить больше минуты ;)) Или нет?

Выбирать первую попавшуюся запись больше минуты ???
20 янв 16, 11:47    [18704925]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Шыфл, можно чисто из любопытства структуру Вашей чудо таблицы...

Если там понатыканы [N]VARCHAR(MAX)/TEXT и прочие лобы, то тут и ладанка из святых мест не поможет.
20 янв 16, 11:57    [18705001]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
o-o
Guest
AlanDenton,
может, у них банально памяти 2 Гб на сервере
(а что, тут был товарищ, далал REORGANIZE 40гигам на компе с двумя гигами)
а могут быть чудо-диски.
у меня есть похожая табличка, записей 133.711.227, объем 10 Гб.
count(*) считается 54 секунды
CREATE TABLE [dbo].[ttt]
	[ID] [int] NOT NULL,
	[COD] [int] NOT NULL,
	[TAB] [varchar](40) NOT NULL,
	[VAL_1] [char](10) NULL,
	[VAL_2] [char](10) NULL,
	[VAL_3] [char](10) NULL

здесь "у меня" это не на ноуте, это их боевой сервер
20 янв 16, 12:20    [18705181]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
komrad
Member

Откуда:
Сообщений: 5249
o-o
у меня есть похожая табличка, записей 133.711.227, объем 10 Гб.
count(*) считается 54 секунды

set statistics io что говорит? сколько там physical reads?
20 янв 16, 12:53    [18705389]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
o-o
Guest
komrad
o-o
у меня есть похожая табличка, записей 133.711.227, объем 10 Гб.
count(*) считается 54 секунды

set statistics io что говорит? сколько там physical reads?

по-честному надо было в первый запуск спрашивать, но пожалуйста:

SQL Server parse and compile time:
CPU time = 10 ms, elapsed time = 10 ms.

(1 row(s) affected)
Table 'ttt'. Scan count 9, logical reads 1263172, physical reads 10762, read-ahead reads 1263172, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:
CPU time = 25484 ms, elapsed time = 70041 ms.

вот и у нас за минуту перевалило
20 янв 16, 13:24    [18705606]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
komrad
Member

Откуда:
Сообщений: 5249
o-o
по-честному надо было в первый запуск спрашивать, но пожалуйста:

неизвестно когда был первый запуск и сколько воды утекло с тех пор (вымыт кэш)
а так, да, согласен

o-o
Table 'ttt'. Scan count 9, logical reads 1263172, physical reads 10762, read-ahead reads 1263172, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

партицирована таблица-то?
20 янв 16, 13:32    [18705677]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
o-o
Guest
7807komrad,
нет.
это вообще куча.
точный CREATE приведен, ничего на ней больше нет
20 янв 16, 13:39    [18705743]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
o-o
Guest
komrad,
7807 это я вас не преумножаю, это не туда проверочный код забился, sorry
20 янв 16, 13:40    [18705759]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
o-o
Guest
komrad
Scan count 9

у нас 8 процессоров, план параллельный,
9 это 8 threads (8 table accesses) + 1 table access
20 янв 16, 14:05    [18705959]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
o-o
Guest
вот с option(maxdop 1) и вынесенными из кэша данными (чистейший physical read):
(1 row(s) affected)
Table 'ttt'. Scan count 1, logical reads 1263172, physical reads 1, read-ahead reads 1263550, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:
CPU time = 16859 ms, elapsed time = 61755 ms.
20 янв 16, 15:20    [18706444]     Ответить | Цитировать Сообщить модератору
 Re: что нам стоит склад построить  [new]
komrad
Member

Откуда:
Сообщений: 5249
o-o
komrad
Scan count 9

у нас 8 процессоров, план параллельный,
9 это 8 threads (8 table accesses) + 1 table access

да, спасибо, понял
20 янв 16, 17:44    [18707481]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить