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

Откуда:
Сообщений: 679
Всем привет!

Есть таблица с детализацией транзакций. Таблица разбита на партиции. На каждый день создается своя партиция по полю datetime.

Требуется быстро подсчитать кол-во строк за период N дней. Как это можно сделать ? Можно ли использовать хинты?
В таблице есть кластреный индекс по полю client_id.
select count(*) FROM table WHERE datetime between @date1 AND @date2+'23:59:59'   


Я бы мог использовать подсчет кол-во строк в портициях и сложить их, но у меня нет 100% уверености что в одной из партиций не будет данных за M дней из-за какого-либо сбоя.
6 дек 12, 22:11    [13590952]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 33970
Блог
секции можно создать заранее, тогда никакого сбоя не будет,

в таблице нет ключей?
6 дек 12, 22:19    [13590965]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

Откуда:
Сообщений: 679
Критик
секции можно создать заранее, тогда никакого сбоя не будет,

в таблице нет ключей?


Секции вначале создаются, а потом загружаются данные.

Все равно "душа" не спокойна. WHere кажется надежным.
6 дек 12, 22:26    [13590972]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

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


Номер партиции из скрипта не совпадает с SELECT $PARTITION.pf('2012-11-27'),$PARTITION.pf('2012-11-28');

Пример скрипта взят с другого форума

SELECT	t.name [table], p.rows, p.partition_number, v.boundary_id, v.value
FROM	sys.tables t
JOIN	sys.partitions p
On	p.object_id = t.object_id
INNER JOIN	sys.partition_range_values v 
ON	v.boundary_id = p.partition_number 
WHERE	is_ms_shipped = 0
order by [table]
6 дек 12, 23:29    [13591078]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

Откуда:
Сообщений: 679
http://msdn.microsoft.com/en-us/library/ms175012(v=sql.105).aspx

не внушает доверие фраза - rows Approximate number of rows in this partition.
6 дек 12, 23:46    [13591112]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Testor1,

Самая тема использовать Column Store. count будет считаться очень быстро. Правда придется как-то обрабатывать ситуацию с неизменяемостью таблицы, но у вас же секционирование. Возможно имеет смысл разделить подсчет архива + текущей таблицы, которая потом будет подключена как новая секция.
Это все если 2012 сервер конечно.
6 дек 12, 23:50    [13591124]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

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

Сервер 2008 R2.

Думаю может задачу полностью опишу.

Каждый день я загружаю новую порцию данных и делаю элементарную проверку, что данные не содержат аномалий типа слишком мало или слишком много строк от среднего арифметического за N дней. где N настраиваемый параметр.

Я подсчитываю кол-во строк за текущий день и отдельно среднее кол-во строк за предыдущие N дней. Далее сравниваю эти две величины. Если нет отклонений выше допустимых значений, то перехожу к следующему этапу обработки данных.

Все работает, но скорость подсчета строк меня не устраивает.
7 дек 12, 00:02    [13591147]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 33970
Блог
скрипт таблицы/индексов имеется?
план запроса имеется?

и возможно правило трех сигм будет лучше, чем ваш расчет среднего
7 дек 12, 00:30    [13591213]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37068
Testor1
SomewhereSomehow,

Сервер 2008 R2.

Думаю может задачу полностью опишу.

Каждый день я загружаю новую порцию данных и делаю элементарную проверку, что данные не содержат аномалий типа слишком мало или слишком много строк от среднего арифметического за N дней. где N настраиваемый параметр.

Я подсчитываю кол-во строк за текущий день и отдельно среднее кол-во строк за предыдущие N дней. Далее сравниваю эти две величины. Если нет отклонений выше допустимых значений, то перехожу к следующему этапу обработки данных.

Все работает, но скорость подсчета строк меня не устраивает.
sys.partitions.rows хватит за глаза для этой проверки.
7 дек 12, 00:38    [13591238]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
invm
Member

Откуда: Москва
Сообщений: 9405
Testor1,

Индексированное представление не пробовали?
7 дек 12, 00:38    [13591239]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

Откуда:
Сообщений: 679
invm
Testor1,

Индексированное представление не пробовали?


Если так как написал - да, то выборка за тот же период работает в 3 раза медленнее

CREATE VIEW [dbo].[vwr_agr_transactions] WITH SCHEMABINDING AS
SELECT     CAST(datetime AS DATE) AS date, COUNT_BIG(*) AS records
FROM         dbo.tb_transactions
GROUP BY CAST(datetime AS DATE)

GO

CREATE CLUSTERED INDEX IX_date  ON vwr_agr_transactions(DATE);
7 дек 12, 09:11    [13591794]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

Откуда:
Сообщений: 679
Гавриленко Сергей Алексеевич
Testor1
SomewhereSomehow,

Сервер 2008 R2.

Думаю может задачу полностью опишу.

Каждый день я загружаю новую порцию данных и делаю элементарную проверку, что данные не содержат аномалий типа слишком мало или слишком много строк от среднего арифметического за N дней. где N настраиваемый параметр.

Я подсчитываю кол-во строк за текущий день и отдельно среднее кол-во строк за предыдущие N дней. Далее сравниваю эти две величины. Если нет отклонений выше допустимых значений, то перехожу к следующему этапу обработки данных.

Все работает, но скорость подсчета строк меня не устраивает.
sys.partitions.rows хватит за глаза для этой проверки.



Какие-то непонятки с syspartions. Кол-во строк в партиции не совпадает с кол-во строк из запроса.
Select со скриншота показывает, что дата почему - в трех партициях, а partition function показывает другую партицию для 28 числа.

Что не так?

К сообщению приложен файл. Размер - 70Kb
7 дек 12, 09:29    [13591919]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37068
Что у вас там не совпадает? У вас в 147й партиции 2кк записей и там и там.
7 дек 12, 09:49    [13592042]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
Testor1,

Очень близко к теме
13235433
7 дек 12, 09:56    [13592088]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
invm
Member

Откуда: Москва
Сообщений: 9405
Testor1
Если так как написал - да, то выборка за тот же период работает в 3 раза медленнее

CREATE VIEW [dbo].[vwr_agr_transactions] WITH SCHEMABINDING AS
SELECT     CAST(datetime AS DATE) AS date, COUNT_BIG(*) AS records
FROM         dbo.tb_transactions
GROUP BY CAST(datetime AS DATE)

GO

CREATE CLUSTERED INDEX IX_date  ON vwr_agr_transactions(DATE);
А with(noexpand) при использовании не забыли указать?
7 дек 12, 10:23    [13592259]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Гость333
Member

Откуда:
Сообщений: 3683
invm
А with(noexpand) при использовании не забыли указать?

Секционирование работает только на Entreprise Edition (ну и на Developer, понятно).
На энтерпрайзе этот хинт включен по умолчанию.
7 дек 12, 10:31    [13592318]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

Откуда:
Сообщений: 679
Гавриленко Сергей Алексеевич
Что у вас там не совпадает? У вас в 147й партиции 2кк записей и там и там.


Почему в селекте за 28 число видно три партиции - 145,144,146, а функция за 28 число возвращает значение - 147 ?
7 дек 12, 10:36    [13592351]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

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

select *
from vwr_agr_transactions with(noexpand)
WHERE date between '2012-08-01' and '2012-08-03'


так летает. спасибо !!!

Вопрос еще. На сколько наличие Viewer на таблице будет тормозить импорт данных в эту таблицу? В теории должно быть сильное влияние?
7 дек 12, 10:43    [13592412]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
invm
Member

Откуда: Москва
Сообщений: 9405
Гость333
invm
А with(noexpand) при использовании не забыли указать?

Секционирование работает только на Entreprise Edition (ну и на Developer, понятно).
На энтерпрайзе этот хинт включен по умолчанию.
Если оптимизатор сочтет запрос "тривиальным", то индексированное представление, если явно не указано noexpand, испольлзовано не будет.
7 дек 12, 10:46    [13592443]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

Откуда:
Сообщений: 679
Гость333
invm
А with(noexpand) при использовании не забыли указать?

Секционирование работает только на Entreprise Edition (ну и на Developer, понятно).
На энтерпрайзе этот хинт включен по умолчанию.


Сервер Enterprise
7 дек 12, 11:00    [13592588]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Гость333
Member

Откуда:
Сообщений: 3683
invm
Гость333
пропущено...

Секционирование работает только на Entreprise Edition (ну и на Developer, понятно).
На энтерпрайзе этот хинт включен по умолчанию.
Если оптимизатор сочтет запрос "тривиальным", то индексированное представление, если явно не указано noexpand, испольлзовано не будет.

Спасибо, буду знать.

Testor1
Почему в селекте за 28 число видно три партиции - 145,144,146, а функция за 28 число возвращает значение - 147 ?
7 дек 12, 11:13    [13592695]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Сорри, случайно отправил.

Testor1
Почему в селекте за 28 число видно три партиции - 145,144,146, а функция за 28 число возвращает значение - 147 ?
[/quot]

У вас там таблицы разные? А функции секционирования у них тоже разные? А в функциях секционирования — range left или range right?
7 дек 12, 11:14    [13592708]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Гость333
invm
пропущено...
Если оптимизатор сочтет запрос "тривиальным", то индексированное представление, если явно не указано noexpand, испольлзовано не будет.

Спасибо, буду знать.

На всякий случай, уточню что "тривиальный" это не в смысле удовлетворяющий тривиальному плану. Это не обязательно. Просто сопоставление вью с запросом(в который и был развернут вью сначала) - дорогая операция, то если оптимизатор считает что нашел достаточно хороший план без сопоставления, то он может и не использовать вью.
7 дек 12, 11:39    [13592929]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

Откуда:
Сообщений: 679
Гость333
Сорри, случайно отправил.

Testor1
Почему в селекте за 28 число видно три партиции - 145,144,146, а функция за 28 число возвращает значение - 147 ?


У вас там таблицы разные? А функции секционирования у них тоже разные? А в функциях секционирования — range left или range right?[/quot]

Таблица одна и фнукция для нее одна. Партиций много и файловых групп (на каждый день).
используется RIGHT.

Каждый загружаемый файл может содержать часть записей за предыдущий день.
7 дек 12, 11:43    [13592979]     Ответить | Цитировать Сообщить модератору
 Re: Быстрый COUNT(*)  [new]
Testor1
Member

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

А что будет при bulk insert ? тормозить система не будет из-за наличия view и index ?
7 дек 12, 11:49    [13593023]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить