2013-06-05 6 views
0

Мы разрабатываем приложение с одной функцией управления платежами для людей. Платеж будет записан в строке в таблице, со следующими полями:Гранулярность строк данных

PersonId (INT) 
TransactionDate (DATETIME) 
Amount (MONEY) 
PaymentTypeId (INT) 
... 
... 
... 

Похоже, мы имеем дело с около 8000 людей, которые мы отправляем платежи, и новая транзакция на человека добавляется ежедневно (Around 8 000 вставок в день). Это означает, что через 7 лет (время, необходимое для хранения данных), у нас будет более 20 000 000 строк.

Мы получаем на 10% больше людей в год, поэтому это число немного увеличивается.

Наиболее распространенным запросом является получение СУММЫ (суммы) на человека, где Дата транзакции между датой начала и датой окончания.

SELECT PersonId, SUM(Amount) 
FROM Table 
WHERE PaymentTypeId = x 
AND TransactionDate BETWEEN StartDate AND EndDate 
GROUP BY PersonId 

Вопрос в том, будет ли это проблемой производительности для SQL Server 2012? Или 20 000 000 строк не так уж плохо?

Я бы предположил, что кластерный индекс на PersonID? (Чтобы сгруппировать их), но это приведет к очень медленным вставкам/обновлениям?

Индекс на TransactionDate?

+0

Возможно, это не связано с вопросом, но не является ли тип данных ДЕНЕГ опасным и бесполезным? – kyooryu

+0

Очень возможно ... Я буду использовать лучший тип данных. – Craig

+0

На самом деле, с кластеризованным индексом ** NOT ** обязательно означает медленные вставки - ** совсем наоборот! ** См. Превосходное сообщение в блоге Кимберли Триппа, в котором обсуждается преимущество ** хорошего кластерного индекса] (http: /www.sqlskills.com/blogs/kimberly/the-clustered-index-debate-continues/) - первое, что она делает, это: * Вкладыши быстрее *! –

ответ

0

Если запрос выбирает на основе TransactionDate и PaymentTypeId, а также нуждается в PersonId и Amount в то же самое, я бы рекомендовал поставить некластеризованный индекс на TransactionDate и PaymentTypeId и в том числе те другие два столбца в индексе:

CREATE NONCLUSTERED INDEX IX_Table_TransactionDate 
ON dbo.Table (TransactionDate, PaymentTypeId) 
INCLUDE (PersonId, Amount) 

Таким образом, ваш запрос может быть удовлетворен только из этого индекса - нет необходимости возвращаться к фактическим полным страницам данных.

Также: если у вас есть годы, которые могут быть «финализированы» (без изменений), вы могли бы предварительно вычислить и сохранить некоторые из этих суммирования, например. за каждый день, за каждый месяц и т. д. При таком подходе определенные запросы могут просто вытащить предварительно вычисленные суммы из таблицы, вместо того, чтобы снова вычислить сумму в тысячах строк.

+0

Спасибо. Однако я не следую «финализированному» биту. Хранить суммированные данные в другой таблице? – Craig

Смежные вопросы