Агрегаты SQL Server для очень больших таблиц - PullRequest
5 голосов
/ 03 октября 2009

У нас есть таблица с 17Mil строками, содержащими атрибуты продукта, скажем, они:

brandID, sizeID, colorID, цена, shapeID

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

select brandID, sizeID, count(*) 
from table where colorID in (1,2,3) and price=10 and shapeID=17
--"additional complex where clause here"
group by brandID, sizeID
order by brandID, sizeID

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

Я думаю, что мы достигли нашей способности индексировать эту таблицу, поэтому я не думаю, что какое-то количество индексов приведет нас к почти мгновенным результатам.

Я очень мало знаю об OLAP или других аналитических службах, но как быть с SQL Server, который может предварительно фильтровать или предварительно агрегировать эту таблицу, чтобы можно было выполнять запросы, подобные приведенным выше (или аналогичные, возвращающие эквивалентные данные)? ИЛИ Как лучше всего обрабатывать произвольные операторы where в очень большой таблице?

Ответы [ 4 ]

4 голосов
/ 03 октября 2009

Я думаю, что это идеальный кандидат для куба Олапа. У меня есть данные фактов с сотнями миллионов строк. Я делал запросы, которые вы описали выше, и запросы возвращались через несколько минут. Я переместил это в куб OLAP, и запросы теперь почти мгновенные. Есть немного кривой обучения для olap. Я настоятельно рекомендую вам найти руководство по простому построению кубов, чтобы разобраться с ним. Коллеги из DBA годами рассказывали мне о кубах, и я так и не понял. Теперь я не знаю, почему я так долго обходился без него.

В дополнение к OLAP вы также можете исследовать индексированные представления, но если вы разделяете данные несколькими способами, это может оказаться невозможным.

0 голосов
/ 03 октября 2009

Если вы используете SQL 2008 и у вас есть определенная часто используемая фильтрация, рассмотрите возможность использования отфильтрованных индексов (возможно, в сочетании с индексами INCLUDE, как предложил gbn).

Скажем, у вас есть только пять значений sizeID. Вы можете разбить ваши текущие индексы на несколько отфильтрованных индексов (например, «WHERE sizeID = 1»).

Использование фильтрации в сочетании с INCLUDE может заставить ваши запросы возвращать намного быстрее.

Справка: Изучение отфильтрованных индексов SQL Server 2008

0 голосов
/ 03 октября 2009

Зависит от вашего индекса и схемы

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

CREATE INDEX IX_foo ON table (shapeID, price, colorID) INCLUDE (brandID, sizeID)
CREATE INDEX IX_foo ON table (shapeID, price, colorID, brandID, sizeID)

Однако вы добавили «дополнительный комплекс where здесь», который смягчает хороший ответ

Мое мышление:

  • Предложение WHERE важно, потому что это уменьшает количество строк
  • ORDER BY менее важен, чем совокупность / WHERE
  • Обложка запроса для удаления поиска ключей

Дополнительные вещи:

  • ColorID в (1,2,3) плох, потому что это ИЛИ
  • Убедитесь, что типы данных параметров соответствуют типам столбцов точно , чтобы избежать неявных преобразований
  • Вы можете поменять местами shapeID, Price и colorID, чтобы увидеть, что лучше (или создать несколько индексов и посмотреть, какой из них используется)
  • У вас есть узкое место на сервере (например, работает на SQL Express и т. Д.)?
0 голосов
/ 03 октября 2009

Без каких-либо подробностей относительно структуры таблиц, физической среды и (не) кластерных индексов и т. Д. Первое место, которое я бы искал, - это «Показать план выполнения» для запроса, а также помощник по настройке ядра СУБД и профилировщик SQL. Надеюсь это поможет.

...