Выбрать в памяти оптимизированную таблицу

У меня есть хранимая процедура, которая преобразует некоторые динамические SQL в временную таблицу или представление в зависимости от настройки базы данных. Это используется для "настройки" функциональности базы данных между различными клиентами в зависимости от размера данных, то есть создание временной таблицы занимает больше времени, но требуется больше времени для настройки, представление создается быстро, но для чтения требуется немного больше времени.

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

Мой код на данный момент будет иметь такой формат:

SELECT TOP 10 *
INTO FavoriteCustomers
FROM Customers
ORDER BY Spend DESC

Как видите, я не объявляю таблицу, просто использую select into. Есть ли способ выбрать SELECT INTO оптимизированную память таблицы? Я могу использовать:

sys.dm_exec_describe_first_result_set(@mySQLhere)

Что дает мне определение столбца для TSQL, который я передаю. Затем используйте эту информацию для предварительной сборки таблицы и вставки в нее, но я надеюсь, что, если возможно, будет более аккуратный метод.

У кого-нибудь есть какие-нибудь решения? Поиск просто уводит меня с пути, как добавить данные в создание MOT, а не MOT, как часть выбора.

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

В настоящее время используются несколько серверов, функции MOT реализуются только в SQL2016.

Спасибо заранее.

1 ответ

Решение
CREATE PROC [engine].[usp_CreateDynamicContent]
    @ContentName AS NVARCHAR(MAX)
,   @NTS_SessionID NVARCHAR(MAX)
,   @SelectSQL NVARCHAR(MAX)
,   @PrimaryKeyField NVARCHAR(MAX) = NULL
,   @NonClusteredIndexField NVARCHAR(MAX) = NULL
,   @debug BIT = 0
AS
    BEGIN

        DECLARE @ContentType AS NVARCHAR(MAX)
        DECLARE @dcName AS NVARCHAR(MAX)
        DECLARE @strSQL AS NVARCHAR(MAX)

        SET @dcName = 'tmp.dc_' + @ContentName + '_' + @NTS_SessionID

        IF OBJECT_ID(@dcName, 'V') IS NOT NULL /* Drop the view if it exists */
            BEGIN
                SET @strSQL = 'DROP VIEW ' + @dcName
                IF @debug = 1
                    PRINT (@strSQL)
                EXEC (@strSQL)
            END

        IF OBJECT_ID(@dcName) IS NOT NULL /* Drop the table if it exists */
            BEGIN
                SET @strSQL = 'DROP TABLE ' + @dcName
                IF @debug = 1
                    PRINT (@strSQL)
                EXEC (@strSQL)
            END

        /* This is my database listing types for each table. */
        SELECT  @ContentType = ContentType
        FROM    guid.DynamicContents
        WHERE   ContentName = @ContentName

        IF @ContentType = 'VIEW'
            BEGIN
                SET @strSQL = 'CREATE VIEW ' + @dcName + ' AS' + CHAR(13) + @SelectSQL
                IF @debug = 1
                    PRINT (@strSQL)
                EXEC (@strSQL)
            END
        ELSE
            IF @ContentType IN ('TABLE', 'MOT')
                BEGIN
                    SET @strSQL = ''
                    SELECT  @strSQL = @strSQL + ',' + CHAR(10) + '[' + name + '] ' + system_type_name + CASE WHEN @PrimaryKeyField IS NOT NULL
                                                                                                                  AND @ContentType = 'MOT' THEN ' NOT NULL PRIMARY KEY NONCLUSTERED'
                                                                                                             ELSE ''
                                                                                                        END + CHAR(13)
                    FROM    sys.dm_exec_describe_first_result_set(@SelectSQL, NULL, 0)
                    SET @strSQL = STUFF(@strSQL, 1, 1, 'CREATE TABLE ' + @dcName + '(')

                    IF @PrimaryKeyField IS NOT NULL
                        AND @ContentType = 'TABLE'
                        BEGIN
                            SET @strSQL = @strSQL + CHAR(10) + ',CONSTRAINT pk_' + @ContentName + '_' + @NTS_SessionID + ' PRIMARY KEY (' + @PrimaryKeyField + ')' + CHAR(10)
                        END

                    SET @strSQL = @strSQL + ')'
                    IF @debug = 1
                        PRINT (@strSQL)
                    EXEC (@strSQL)

                    IF @NonClusteredIndexField IS NOT NULL
                        AND @ContentType = 'TABLE'
                        BEGIN
                            SET @strSQL = 'CREATE NONCLUSTERED INDEX ix_' + @ContentName + '_' + @NonClusteredIndexField + ' ON ' + @dcName + ' (' + @NonClusteredIndexField + ')'
                            IF @debug = 1
                                PRINT (@strSQL)
                            EXEC (@strSQL)
                        END

                    /* This section added in as I use cte's quite a lot */
                    IF @SelectSQL LIKE '%/* INSERT HERE */%'
                        BEGIN
                            SET @strSQL = REPLACE(@SelectSQL, '/* INSERT HERE */', 'INSERT INTO ' + @dcName)
                        END
                    ELSE
                        BEGIN
                            SET @strSQL = 'INSERT INTO ' + @dcName + CHAR(13) + @SelectSQL 
                        END
                    IF @debug = 1
                        PRINT (@strSQL)
                    EXEC (@strSQL)
                END

    END
Другие вопросы по тегам