У меня огромная таблица с более чем ста миллионами строк, и я должен запросить эту таблицу, чтобы вернуть набор данных за минимальное время.
Итак, я создал тестовую среду с этимопределение таблицы:
CREATE TABLE [dbo].[Test](
[Dim1ID] [nvarchar](20) NOT NULL,
[Dim2ID] [nvarchar](20) NOT NULL,
[Dim3ID] [nvarchar](4) NOT NULL,
[Dim4ID] [smalldatetime] NOT NULL,
[Dim5ID] [nvarchar](20) NOT NULL,
[Dim6ID] [nvarchar](4) NOT NULL,
[Dim7ID] [nvarchar](4) NOT NULL,
[Dim8ID] [nvarchar](4) NOT NULL,
[Dim9ID] [nvarchar](4) NOT NULL,
[Dim10ID] [nvarchar](4) NOT NULL,
[Dim11ID] [nvarchar](20) NOT NULL,
[Value] [decimal](21, 6) NOT NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[Dim1ID] ASC,
[Dim2ID] ASC,
[Dim3ID] ASC,
[Dim4ID] ASC,
[Dim5ID] ASC,
[Dim6ID] ASC,
[Dim7ID] ASC,
[Dim8ID] ASC,
[Dim9ID] ASC,
[Dim10ID] ASC,
[Dim11ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Эта таблица является таблицей фактов архитектуры схемы Star (факт / измерения).Как видите, у меня есть кластеризованный индекс по всем столбцам, кроме столбца «Значение».
Я заполнил эти данные ок.10 000 000 строк для целей тестирования.Фрагментация в настоящее время составляет 0,01%.
Я хотел бы повысить производительность при чтении набора строк из этой таблицы с помощью этого запроса:
DECLARE @Dim1ID nvarchar(20) = 'C1'
DECLARE @Dim9ID nvarchar(4) = 'VRT1'
DECLARE @Dim10ID nvarchar(4) = 'S1'
DECLARE @Dim6ID nvarchar(4) = 'FRA'
DECLARE @Dim7ID nvarchar(4) = '' -- empty = all
DECLARE @Dim8ID nvarchar(4) = '' -- empty = all
DECLARE @Dim2 TABLE ( Dim2ID nvarchar(20) NOT NULL )
INSERT INTO @Dim2 VALUES ('A1'), ('A2'), ('A3'), ('A4');
DECLARE @Dim3 TABLE ( Dim3ID nvarchar(4) NOT NULL )
INSERT INTO @Dim3 VALUES ('P1');
DECLARE @Dim4ID TABLE ( Dim4ID smalldatetime NOT NULL )
INSERT INTO @Dim4ID VALUES ('2009-01-01'), ('2009-01-02'), ('2009-01-03');
DECLARE @Dim11 TABLE ( Dim11ID nvarchar(20) NOT NULL )
INSERT INTO @Dim11 VALUES ('Var0001'), ('Var0040'), ('Var0060'), ('Var0099')
SELECT RD.Dim2ID,
RD.Dim3ID,
RD.Dim4ID,
RD.Dim5ID,
RD.Dim6ID,
RD.Dim7ID,
RD.Dim8ID,
RD.Dim9ID,
RD.Dim10ID,
RD.Dim11ID,
RD.Value
FROM dbo.Test RD
INNER JOIN @Dim2 R
ON RD.Dim2ID = R.Dim2ID
INNER JOIN @Dim3 C
ON RD.Dim3ID = C.Dim3ID
INNER JOIN @Dim4ID P
ON RD.Dim4ID = P.Dim4ID
INNER JOIN @Dim11 V
ON RD.Dim11ID = V.Dim11ID
WHERE RD.Dim1ID = @Dim1ID
AND RD.Dim9ID = @Dim9ID
AND ((@Dim6ID <> '' AND RD.Dim6ID = @Dim6ID) OR @Dim6ID = '')
AND ((@Dim7ID <> '' AND RD.Dim7ID = @Dim7ID) OR @Dim7ID = '')
AND ((@Dim8ID <>'' AND RD.Dim8ID = @Dim8ID) OR @Dim8ID = '')
Я проверил этот запрос, и этовернул 180 строк с таким временем: 1-е исполнение: 1 мин 32 с;2-е выполнение: 1 минута .
Я хотел бы вернуть данные через несколько секунд, если это возможно.
Я думаю, что могу добавить некластеризованные индексы, но я неуверен, что лучший способ - это установить некластеризованные индексы!Если сортировка данных заказа в этой таблице может улучшить производительность?Или есть другие решения, кроме индексов?
Спасибо.