повышение производительности выбора временной таблицы SQL Server - PullRequest
0 голосов
/ 19 февраля 2019

У меня есть временная таблица, структура которой приведена ниже.Его возвращение 3,8 миллиона записей.Это занимает 5 минут.Есть ли способ улучшить производительность.Какой должен быть правильный индекс для этой временной таблицы?Нужно ли использовать раздел?Если да, то как правильно его использовать

CREATE TABLE  #FinalResultTable                
 (              
    RowNum INT  PRIMARY KEY NONCLUSTERED IDENTITY(1,1),              
    [Disclosure Category] NVARCHAR(250) NULL,              
    [Line #] INT NULL,                 
    [AllocationProcessId] BIGINT NULL,              
    [Allocation Name] VARCHAR(50) NULL,                
    [Line Description (Long)] NVARCHAR(3000) NULL,               
    [Line Description (Short)]  NVARCHAR(500) NULL,         
    [UniqueTransactionId] INT NULL,         
    [TransactionName] VARCHAR(125) NULL,                
    [Partner #] INT NULL,                
    [Partner Name] VARCHAR(2000) NULL,                
    [RuleName] VARCHAR(128) NULL,                
    [Tag Group1] NVARCHAR(75) NULL,                
    [Tag Group2] NVARCHAR(75) NULL,                
    [Tag Group3] NVARCHAR(75) NULL,                
    [Tag Group4] NVARCHAR(75) NULL,                
    [Segment Start Date] DATE NULL,                
    [Segment End Date] DATE NULL,                
)   


CREATE CLUSTERED INDEX IX_FinalResultTable 
    ON #FinalResultTable ([Partner #],[Disclosure Category]);

до того, как данные о выборке будут вставлены в эту временную таблицу из многих других таблиц.

SELECT 
 [RowNum],              
[Disclosure Category],              
[Line #],                 
[AllocationProcessId],              
[Allocation Name],                
[Line Description (Long)],               
[Line Description (Short)],         
[UniqueTransactionId],         
[TransactionName],                
[Partner #],                
[Partner Name],                
[RuleName],                
[Tag Group1],                
[Tag Group2],                
[Tag Group3],                
[Tag Group4],                
[Segment Start Date],                
[Segment End Date]                
FROM #FinalResultTable

1 Ответ

0 голосов
/ 20 февраля 2019

Вы не можете ускорить SELECT с индексами, если вы планируете получить все записи.Индексы хороши для выбора определенных строк с определенными критериями или выборки строк в определенном порядке (у вашего SELECT также нет ORDER BY).

Стоит упомянуть одну вещь - как вы загружаете своиТаблица.Использование CREATE TABLE + INSERT INTO заставляет журнал SQL Server вставлять каждую строку и занимает намного больше времени, чем SELECT INTO (без создания таблицы), в которой ведется минимальное ведение журнала.Обязательно правильно приведите типы данных из SELECT, если вы переключитесь на этот подход.

Поэтому вместо:

IF OBJECT_ID('tempdb..#FinalResultTable') IS NOT NULL
    DROP TABLE #FinalResultTable

CREATE TABLE  #FinalResultTable                
(              
    /*Columns*/              
)

INSERT INTO #FinalResultTable
(
    /*Columns*/  
)
SELECT
    /*Columns*/
FROM
    /*Tables*/

Вы переключаетесь на:

IF OBJECT_ID('tempdb..#FinalResultTable') IS NOT NULL
    DROP TABLE #FinalResultTable

SELECT
    /*
    Columns with the proper data type cast (if needed), for example:

        Column1 = CONVERT(VARCHAR(100), Column1 + 'SomeText'),
        Column2 = CONVERT(INT, VarcharColumn)
    */
INTO
    #FinalResultTable
FROM
    /*Tables*/

Если вы не упорядочиваете свои данные и просто используете эту временную таблицу для выбора всех строк позже, вы можете избежать создания любого индекса для него, так как для этого потребуетсяв то время как генерировать один или переупорядочить все данные (если они кластеризованы).Поэтому не создавайте кластеризованный индекс IX_FinalResultTable, а также не объявляйте PRIMARY KEY для своего столбца IDENTITY, используйте RowNum INT IDENTITY.Это сделает вашу временную таблицу кучей, а не реальной таблицей, помните, что большая часть отфильтрованного выбора значительно снизит производительность, если вы использовали поиск по [Partner #].

Если вам нужен кластерный индекс по[Partner #], [Disclosure Category], загрузка таблицы, уже упорядоченной этими двумя, фактически уменьшит время создания индекса.Обязательно создайте индекс после таблицы, загруженной, а не раньше, так как она быстрее.

SELECT
    /*
    Columns with the proper data type cast (if needed), for example:

        Column1 = CONVERT(VARCHAR(100), Column1 + 'SomeText'),
        Column2 = CONVERT(INT, VarcharColumn)
    */
INTO
    #FinalResultTable
FROM
    /*Tables*/
ORDER BY
    [Partner #],            -- Or the expression that resolves as this column
    [Disclosure Category]   -- Or the expression that resolves as this column

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...