Как улучшить производительность при использовании различного количества - PullRequest
2 голосов
/ 13 июля 2011

Моя БД - SQL SERVER 2008

У меня есть большая таблица с 100 миллионами строк и 50 столбцами.

Весь тип данных int.

Тогда мой запрос похож на ....

Select Count(distinct col5) , Count(distinct col8) , Sum(Col 30) , Sum(Col 49) 
Group by Col1 

Select Count(distinct col5) , Count(distinct col8) , Sum(Col 30) , Sum(Col 49) 
Group by Col1,col2

.....


Select Count(distinct col5) , Count(distinct col8) , Sum(Col 30) , Sum(Col 49) 
Group by Col1 ,Col2,Col3,Col4,Col6,Col7

(about 180 queries ...like above)

Но производительность очень плохая, когда я использую отчетливый счет.

Итак, кто может научить меня, как его улучшить, пожалуйста?

а в моем случае как долго может стоить лучшее решение?

очень спасибо за советы ....

Ответы [ 3 ]

3 голосов
/ 13 июля 2011

Эти запросы (без предложений WHERE) вряд ли можно оптимизировать, поскольку им нужно посещать каждую запись, чтобы вычислить суммы независимо от того, что.

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

2 голосов
/ 13 июля 2011

Индексирование столбцы увеличат производительность, но вставки / обновления могут замедлиться.

EDIT
Сделал еще несколько тестов с индексами, как предложено в комментариях. Я получил эти результаты: (с и без индексов) enter image description here

Использование этого запроса: (MAXDOP ограничивает запрос использованием одного процессора для более сопоставимых планов, без подсказки MAXDOP стоимость составила 36% против 64%)

SELECT COUNT(DISTINCT fkCustomCultureID), SUM(fkCustomCultureTypeID)
FROM tblTest
GROUP BY fkCategoryTypeID
OPTION (MAXDOP 1)

На этой таблице:

CREATE TABLE [dbo].[TblTest](
    [fkID] [sql_variant] NOT NULL,
    [fkCustomCultureID] [bigint] NOT NULL,
    [fkCategoryTypeID] [int] NOT NULL,
    [fkCustomCultureTypeID] [int] NOT NULL
) ON [PRIMARY]

GO

CREATE NONCLUSTERED INDEX [IX_Test1] ON [dbo].[TblTest] 
(
    [fkCustomCultureID] ASC,
    [fkCategoryTypeID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
0 голосов
/ 13 июля 2011

Если вам не всегда нужны все столбцы, просто собираемся выбросить их, вы рассматривали возможность разделения таблицы?Это должно быть хорошо при условии, что вы можете изменить таблицу таким образом (что, к сожалению, обычно имеет место)

Если вы разделите таблицу, скажем, на 5 таблиц (примерно) 10 столбцов и назначите идентификатор (кластеризованный индекс)для каждой существующей в данный момент строки вам придется сканировать в 5 раз меньше диска (при условии, что все ваши столбцы находятся на одном и том же, помня, что если у вас нет индекса, он всегда будет извлекать все столбцы для всего).

Кроме создания индекса для каждого столбца, я предлагаю вам взглянуть на ваши запросы и попытаться решить, есть ли некоторые столбцы, которые вызываются очень редко, и другие, которые вызываются все время (особенно вместе).Когда я делал это в прошлом, я увидел значительные улучшения как прямой результат разделения таблицы на таблицы «Всегда», «Часто», «Редко» и «Почти никогда» вместе с таблицей «Обычно вместе» или двумя там..

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

Если вы действительно хотите лучшую производительность, ятакже может предложить, возможно, посмотреть на замену дисков и обновление оперативной памяти на SQL Server, ваша таблица должна использовать около 20 ГБ пространства, сколько времени потребуется текущим дискам для чтения 20 ГБ данных с диска в ОЗУ?Это будет ваш нижний предел времени выполнения запроса (если он не всегда в оперативной памяти, в этом случае даже при таком большом количестве запросов данных не должно быть слишком много времени)

...