В чем разница между временной таблицей и табличной переменной в SQL Server?

в SQL Server 2005 мы можем создать временные таблицы одним из двух способов:

declare @tmp table (Col1 int, Col2 int);

или

create table #tmp (Col1 int, Col2 int);

каковы различия между этими двумя? Я читал противоречивые мнения о том, использует ли @tmp все еще tempdb, или если все происходит в памяти.

в каких сценариях один из них выполняет другой?

11 ответов


Существует несколько различий между временными таблицами (#tmp) и табличными переменными (@tmp), хотя использование tempdb не является одним из них, как указано в ссылке MSDN ниже.

Как правило, для малых и средних объемов данных и простых сценариев использования вы должны использовать табличные переменные. (Это слишком широкое руководство с, Конечно, множеством исключений-см. ниже и следующие статьи.)

некоторые моменты, которые следует учитывать при выборе между ними:

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

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

  • переменные таблицы не участвуют в транзакциях и SELECTs неявно с NOLOCK. Поведение транзакции может быть очень полезно, например, если вы хотите откатить в середине процедуры, то переменные таблицы, заполненные во время этой транзакции, все равно будут заполнены!

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

  • вы можете создать временную таблицу, используя SELECT INTO, которая может быть быстрее писать (хорошо для ad-hoc запросов) и может позволить вам иметь дело с изменением типов данных с течением времени, так как вам не нужно определять структуру временной таблицы заранее.

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

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

  • как табличные переменные и временные таблицы хранятся в базе данных tempdb. Но переменные таблицы (с 2005) по умолчанию для сортировки текущая база данных и временные таблицы, которые принимают параметры сортировки по умолчанию tempdb (ref). Это означает, что вы должны знать о проблемах сортировки, если использование временных таблиц и параметров сортировки БД отличается от tempdb, что вызывает проблемы, если вы хотите сравнить данные в временной таблице с данными в базе данных.

  • глобальные временные таблицы (##tmp) - это еще один тип временной таблицы, доступный для всех сеансов и пользователей.

некоторые дополнительные чтение:


просто глядя на утверждение в принятом ответе, что переменные таблицы не участвуют в регистрации.

кажется вообще неверным, что есть какая-либо разница в количестве ведения журнала (по крайней мере для insert/update/delete операции с самой таблицей, хотя у меня есть С что есть небольшая разница в этом отношении для кэшированных временных объектов в хранимых процедурах из-за дополнительных обновлений системных таблиц).

Я посмотрел на поведение ведения журнала против обоих a @table_variable и #temp таблица для следующих операций.

  1. Удачный Вставить
  2. Многорядная вставка, где оператор откатывается из-за нарушения ограничений.
  3. обновление
  4. удалить
  5. освободить

записи журнала транзакций были почти идентичны для всех операций.

версия переменной таблицы фактически имеет несколько дополнительно записи журнала, потому что он получает запись, добавленную (а затем удаленную)sys.syssingleobjrefs базовая таблица, но в целом было несколько меньше байтов, зарегистрированных чисто как внутреннее имя для переменных таблицы потребляет 236 меньше байтов, чем для #temp таблицы (118 меньше nvarchar символы).

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

:setvar tablename "@T" 
:setvar tablescript "DECLARE @T TABLE"

/*
 --Uncomment this section to test a #temp table
:setvar tablename "#T" 
:setvar tablescript "CREATE TABLE #T"
*/

USE tempdb 
GO    
CHECKPOINT

DECLARE @LSN NVARCHAR(25)

SELECT @LSN = MAX([Current LSN])
FROM fn_dblog(null, null) 


EXEC(N'BEGIN TRAN StartBatch
SAVE TRAN StartBatch
COMMIT

$(tablescript)
(
[4CA996AC-C7E1-48B5-B48A-E721E7A435F0] INT PRIMARY KEY DEFAULT 0,
InRowFiller char(7000) DEFAULT ''A'',
OffRowFiller varchar(8000) DEFAULT REPLICATE(''B'',8000),
LOBFiller varchar(max) DEFAULT REPLICATE(cast(''C'' as varchar(max)),10000)
)


BEGIN TRAN InsertFirstRow
SAVE TRAN InsertFirstRow
COMMIT

INSERT INTO $(tablename)
DEFAULT VALUES

BEGIN TRAN Insert9Rows
SAVE TRAN Insert9Rows
COMMIT


INSERT INTO $(tablename) ([4CA996AC-C7E1-48B5-B48A-E721E7A435F0])
SELECT TOP 9 ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM sys.all_columns

BEGIN TRAN InsertFailure
SAVE TRAN InsertFailure
COMMIT


/*Try and Insert 10 rows, the 10th one will cause a constraint violation*/
BEGIN TRY
INSERT INTO $(tablename) ([4CA996AC-C7E1-48B5-B48A-E721E7A435F0])
SELECT TOP (10) (10 + ROW_NUMBER() OVER (ORDER BY (SELECT 0))) % 20
FROM sys.all_columns
END TRY
BEGIN CATCH
PRINT ERROR_MESSAGE()
END CATCH

BEGIN TRAN Update10Rows
SAVE TRAN Update10Rows
COMMIT

UPDATE $(tablename)
SET InRowFiller = LOWER(InRowFiller),
    OffRowFiller  =LOWER(OffRowFiller),
    LOBFiller  =LOWER(LOBFiller)


BEGIN TRAN Delete10Rows
SAVE TRAN Delete10Rows
COMMIT

DELETE FROM  $(tablename)
BEGIN TRAN AfterDelete
SAVE TRAN AfterDelete
COMMIT

BEGIN TRAN EndBatch
SAVE TRAN EndBatch
COMMIT')


DECLARE @LSN_HEX NVARCHAR(25) = 
        CAST(CAST(CONVERT(varbinary,SUBSTRING(@LSN, 1, 8),2) AS INT) AS VARCHAR) + ':' +
        CAST(CAST(CONVERT(varbinary,SUBSTRING(@LSN, 10, 8),2) AS INT) AS VARCHAR) + ':' +
        CAST(CAST(CONVERT(varbinary,SUBSTRING(@LSN, 19, 4),2) AS INT) AS VARCHAR)        

SELECT 
    [Operation],
    [Context],
    [AllocUnitName],
    [Transaction Name],
    [Description]
FROM   fn_dblog(@LSN_HEX, null) AS D
WHERE  [Current LSN] > @LSN  

SELECT CASE
         WHEN GROUPING(Operation) = 1 THEN 'Total'
         ELSE Operation
       END AS Operation,
       Context,
       AllocUnitName,
       COALESCE(SUM([Log Record Length]), 0) AS [Size in Bytes],
       COUNT(*)                              AS Cnt
FROM   fn_dblog(@LSN_HEX, null) AS D
WHERE  [Current LSN] > @LSN  
GROUP BY GROUPING SETS((Operation, Context, AllocUnitName),())

результаты

+-----------------------+--------------------+---------------------------+---------------+------+---------------+------+------------------+
|                       |                    |                           |             @TV      |             #TV      |                  |
+-----------------------+--------------------+---------------------------+---------------+------+---------------+------+------------------+
| Operation             | Context            | AllocUnitName             | Size in Bytes | Cnt  | Size in Bytes | Cnt  | Difference Bytes |
+-----------------------+--------------------+---------------------------+---------------+------+---------------+------+------------------+
| LOP_ABORT_XACT        | LCX_NULL           |                           | 52            | 1    | 52            | 1    |                  |
| LOP_BEGIN_XACT        | LCX_NULL           |                           | 6056          | 50   | 6056          | 50   |                  |
| LOP_COMMIT_XACT       | LCX_NULL           |                           | 2548          | 49   | 2548          | 49   |                  |
| LOP_COUNT_DELTA       | LCX_CLUSTERED      | sys.sysallocunits.clust   | 624           | 3    | 624           | 3    |                  |
| LOP_COUNT_DELTA       | LCX_CLUSTERED      | sys.sysrowsets.clust      | 208           | 1    | 208           | 1    |                  |
| LOP_COUNT_DELTA       | LCX_CLUSTERED      | sys.sysrscols.clst        | 832           | 4    | 832           | 4    |                  |
| LOP_CREATE_ALLOCCHAIN | LCX_NULL           |                           | 120           | 3    | 120           | 3    |                  |
| LOP_DELETE_ROWS       | LCX_INDEX_INTERIOR | Unknown Alloc Unit        | 720           | 9    | 720           | 9    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysallocunits.clust   | 444           | 3    | 444           | 3    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysallocunits.nc      | 276           | 3    | 276           | 3    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.syscolpars.clst       | 628           | 4    | 628           | 4    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.syscolpars.nc         | 484           | 4    | 484           | 4    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysidxstats.clst      | 176           | 1    | 176           | 1    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysidxstats.nc        | 144           | 1    | 144           | 1    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysiscols.clst        | 100           | 1    | 100           | 1    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysiscols.nc1         | 88            | 1    | 88            | 1    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysobjvalues.clst     | 596           | 5    | 596           | 5    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysrowsets.clust      | 132           | 1    | 132           | 1    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysrscols.clst        | 528           | 4    | 528           | 4    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysschobjs.clst       | 1040          | 6    | 1276          | 6    | 236              |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysschobjs.nc1        | 820           | 6    | 1060          | 6    | 240              |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysschobjs.nc2        | 820           | 6    | 1060          | 6    | 240              |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.sysschobjs.nc3        | 480           | 6    | 480           | 6    |                  |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.syssingleobjrefs.clst | 96            | 1    |               |      | -96              |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | sys.syssingleobjrefs.nc1  | 88            | 1    |               |      | -88              |
| LOP_DELETE_ROWS       | LCX_MARK_AS_GHOST  | Unknown Alloc Unit        | 72092         | 19   | 72092         | 19   |                  |
| LOP_DELETE_ROWS       | LCX_TEXT_MIX       | Unknown Alloc Unit        | 16348         | 37   | 16348         | 37   |                  |
| LOP_FORMAT_PAGE       | LCX_HEAP           | Unknown Alloc Unit        | 1596          | 19   | 1596          | 19   |                  |
| LOP_FORMAT_PAGE       | LCX_IAM            | Unknown Alloc Unit        | 252           | 3    | 252           | 3    |                  |
| LOP_FORMAT_PAGE       | LCX_INDEX_INTERIOR | Unknown Alloc Unit        | 84            | 1    | 84            | 1    |                  |
| LOP_FORMAT_PAGE       | LCX_TEXT_MIX       | Unknown Alloc Unit        | 4788          | 57   | 4788          | 57   |                  |
| LOP_HOBT_DDL          | LCX_NULL           |                           | 108           | 3    | 108           | 3    |                  |
| LOP_HOBT_DELTA        | LCX_NULL           |                           | 9600          | 150  | 9600          | 150  |                  |
| LOP_INSERT_ROWS       | LCX_CLUSTERED      | sys.sysallocunits.clust   | 456           | 3    | 456           | 3    |                  |
| LOP_INSERT_ROWS       | LCX_CLUSTERED      | sys.syscolpars.clst       | 644           | 4    | 644           | 4    |                  |
| LOP_INSERT_ROWS       | LCX_CLUSTERED      | sys.sysidxstats.clst      | 180           | 1    | 180           | 1    |                  |
| LOP_INSERT_ROWS       | LCX_CLUSTERED      | sys.sysiscols.clst        | 104           | 1    | 104           | 1    |                  |
| LOP_INSERT_ROWS       | LCX_CLUSTERED      | sys.sysobjvalues.clst     | 616           | 5    | 616           | 5    |                  |
| LOP_INSERT_ROWS       | LCX_CLUSTERED      | sys.sysrowsets.clust      | 136           | 1    | 136           | 1    |                  |
| LOP_INSERT_ROWS       | LCX_CLUSTERED      | sys.sysrscols.clst        | 544           | 4    | 544           | 4    |                  |
| LOP_INSERT_ROWS       | LCX_CLUSTERED      | sys.sysschobjs.clst       | 1064          | 6    | 1300          | 6    | 236              |
| LOP_INSERT_ROWS       | LCX_CLUSTERED      | sys.syssingleobjrefs.clst | 100           | 1    |               |      | -100             |
| LOP_INSERT_ROWS       | LCX_CLUSTERED      | Unknown Alloc Unit        | 135888        | 19   | 135888        | 19   |                  |
| LOP_INSERT_ROWS       | LCX_INDEX_INTERIOR | Unknown Alloc Unit        | 1596          | 19   | 1596          | 19   |                  |
| LOP_INSERT_ROWS       | LCX_INDEX_LEAF     | sys.sysallocunits.nc      | 288           | 3    | 288           | 3    |                  |
| LOP_INSERT_ROWS       | LCX_INDEX_LEAF     | sys.syscolpars.nc         | 500           | 4    | 500           | 4    |                  |
| LOP_INSERT_ROWS       | LCX_INDEX_LEAF     | sys.sysidxstats.nc        | 148           | 1    | 148           | 1    |                  |
| LOP_INSERT_ROWS       | LCX_INDEX_LEAF     | sys.sysiscols.nc1         | 92            | 1    | 92            | 1    |                  |
| LOP_INSERT_ROWS       | LCX_INDEX_LEAF     | sys.sysschobjs.nc1        | 844           | 6    | 1084          | 6    | 240              |
| LOP_INSERT_ROWS       | LCX_INDEX_LEAF     | sys.sysschobjs.nc2        | 844           | 6    | 1084          | 6    | 240              |
| LOP_INSERT_ROWS       | LCX_INDEX_LEAF     | sys.sysschobjs.nc3        | 504           | 6    | 504           | 6    |                  |
| LOP_INSERT_ROWS       | LCX_INDEX_LEAF     | sys.syssingleobjrefs.nc1  | 92            | 1    |               |      | -92              |
| LOP_INSERT_ROWS       | LCX_TEXT_MIX       | Unknown Alloc Unit        | 5112          | 71   | 5112          | 71   |                  |
| LOP_MARK_SAVEPOINT    | LCX_NULL           |                           | 508           | 8    | 508           | 8    |                  |
| LOP_MODIFY_COLUMNS    | LCX_CLUSTERED      | Unknown Alloc Unit        | 1560          | 10   | 1560          | 10   |                  |
| LOP_MODIFY_HEADER     | LCX_HEAP           | Unknown Alloc Unit        | 3780          | 45   | 3780          | 45   |                  |
| LOP_MODIFY_ROW        | LCX_CLUSTERED      | sys.syscolpars.clst       | 384           | 4    | 384           | 4    |                  |
| LOP_MODIFY_ROW        | LCX_CLUSTERED      | sys.sysidxstats.clst      | 100           | 1    | 100           | 1    |                  |
| LOP_MODIFY_ROW        | LCX_CLUSTERED      | sys.sysrowsets.clust      | 92            | 1    | 92            | 1    |                  |
| LOP_MODIFY_ROW        | LCX_CLUSTERED      | sys.sysschobjs.clst       | 1144          | 13   | 1144          | 13   |                  |
| LOP_MODIFY_ROW        | LCX_IAM            | Unknown Alloc Unit        | 4224          | 48   | 4224          | 48   |                  |
| LOP_MODIFY_ROW        | LCX_PFS            | Unknown Alloc Unit        | 13632         | 169  | 13632         | 169  |                  |
| LOP_MODIFY_ROW        | LCX_TEXT_MIX       | Unknown Alloc Unit        | 108640        | 120  | 108640        | 120  |                  |
| LOP_ROOT_CHANGE       | LCX_CLUSTERED      | sys.sysallocunits.clust   | 960           | 10   | 960           | 10   |                  |
| LOP_SET_BITS          | LCX_GAM            | Unknown Alloc Unit        | 1200          | 20   | 1200          | 20   |                  |
| LOP_SET_BITS          | LCX_IAM            | Unknown Alloc Unit        | 1080          | 18   | 1080          | 18   |                  |
| LOP_SET_BITS          | LCX_SGAM           | Unknown Alloc Unit        | 120           | 2    | 120           | 2    |                  |
| LOP_SHRINK_NOOP       | LCX_NULL           |                           |               |      | 32            | 1    | 32               |
+-----------------------+--------------------+---------------------------+---------------+------+---------------+------+------------------+
| Total                 |                    |                           | 410144        | 1095 | 411232        | 1092 | 1088             |
+-----------------------+--------------------+---------------------------+---------------+------+---------------+------+------------------+

в каких сценариях один из них выполняет другой?

для небольших таблиц (менее 1000 строк) используйте переменную temp, в противном случае используйте временную таблицу.


@wcm-на самом деле, чтобы выбрать переменную таблицы, не только ОЗУ - она может быть частично сохранена на диске.

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

хорошая справочная статья


  1. временная таблица: временная таблица проста в создании и резервном копировании данных.

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

  2. таблица Temp: результат таблицы Temp может использоваться несколькими пользователями.

    переменная таблицы: но переменная таблицы может использоваться только текущим пользователем. 

  3. таблица Temp: таблица Temp будет храниться в базе данных tempdb. Оно сделает сетевой трафик. Когда у нас есть большие данные в таблице temp, он должен работать через базу данных. Будет существовать проблема производительности.

    переменная таблицы: но переменная таблицы будет храниться в физической памяти для некоторых данных, а затем, когда размер увеличится, она будет перемещена в tempdb.

  4. таблица Temp: таблица Temp может выполнять все операции DDL. Это позволяет создать индексы, падать, изменять и т. д..,

    таблица переменных: а переменная table не позволит выполнять операции DDL. Но переменная table позволяет нам создавать только кластеризованный индекс.

  5. временная таблица: временная таблица может использоваться для текущего сеанса или глобального. Чтобы сеанс с несколькими пользователями мог использовать результаты в таблице.

    переменная таблицы: но переменную таблицы можно использовать до этой программы. (Хранимая процедура)

  6. таблица Temp: переменная Temp не может использовать транзакции. Когда мы делаем операции DML с временной таблицей, тогда это может быть откат или фиксация транзакций.

    переменная таблицы: но мы не можем сделать это для переменной таблицы.

  7. таблица Temp: функции не могут использовать переменную temp. Более того, мы не можем выполнить операцию DML в функциях .

    переменная таблицы: но функция позволяет нам использовать переменную таблицы. Но с помощью переменной table Мы можем это сделать.

  8. временные таблицы: хранимая процедура будет выполнять перекомпиляцию (не может использовать один и тот же план выполнения), когда мы используем переменную temp для каждого вызова sub sequent.

    переменной: если переменная не нравится.


для всех вас, кто верит мифу, что временные переменные находятся только в памяти

во-первых, переменная таблицы не обязательно является резидентом памяти. Под давлением памяти страницы, принадлежащие табличной переменной, могут быть вытеснены в tempdb.

Читать статью здесь: TempDB:: переменная таблицы vs локальная временная таблица


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


цитата взята из; профессиональный SQL Server 2012 внутренние и устранение неполадок

статистика Основное различие между таблицами temp и переменными таблицы заключается в том, что статистика не создается по табличным переменным. Это имеет два основных последствий, первым из которых является то, что оптимизатор запросов использует фиксированная оценка числа строк в табличной переменной независимо от содержащихся в нем данных. Кроме того, добавление или удаление данные не изменяют оценку.

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

Модификации Схемы изменения схемы возможны на временном таблицы, но не переменные таблицы. Хотя катионы modifi схемы возможно во временных таблицах, избегайте их использования, потому что они вызывают перекомпиляция операторов, использующих таблицы.

Temporary Tables versus Table Variables

ПЕРЕМЕННЫЕ ТАБЛИЦЫ НЕ СОЗДАЮТСЯ В ПАМЯТИ

есть распространенное заблуждение, что переменные таблицы являются структурами в памяти и как таковой будет работать быстрее, чем временные таблицы. Благодаря DMV называется сис . DM _ db _ session _ space _ usage, который показывает использование tempdb сеанс,вы можете доказать, что это не так. После перезапуска SQL Server очистите DMV, запустите следующий сценарий для confi rm, что ваш сеанс _ id возвращает 0 для user _ objects _ alloc _ page _ count:

SELECT session_id,
database_id,
user_objects_alloc_page_count
FROM sys.dm_db_session_space_usage
WHERE session_id > 50 ;

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

CREATE TABLE #TempTable ( ID INT ) ;
INSERT INTO #TempTable ( ID )
VALUES ( 1 ) ;
GO
SELECT session_id,
database_id,
user_objects_alloc_page_count
FROM sys.dm_db_session_space_usage
WHERE session_id > 50 ;

результаты на моем сервере показывают, что таблице была выделена одна страница в tempdb. Теперь запустите тот же скрипт, но используйте переменную table на этот раз:--6-->

DECLARE @TempTable TABLE ( ID INT ) ;
INSERT INTO @TempTable ( ID )
VALUES ( 1 ) ;
GO
SELECT session_id,
database_id,
user_objects_alloc_page_count
FROM sys.dm_db_session_space_usage
WHERE session_id > 50 ;

какую использовать?

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

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


еще одно различие:

доступ к таблице var можно получить только из операторов процедуры, которая его создает, а не из других процедур, вызываемых этой процедурой или вложенным динамическим SQL (через exec или sp_executesql).

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

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


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


Временная Таблица

временная таблица ведет себя как реальная таблица, но создается во время выполнения. Его работа похожа на настоящий стол. Мы можем делать почти все операции, которые возможны в реальных таблицах. Мы можем использовать операторы DDL, такие как ALTER, CREATE, DROP на временных таблицах.

любые изменения в структуре временной таблицы возможны после создания. Временная таблица, хранящаяся в базе данных" tempdb " системных баз данных.

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

Переменной В Таблице

Это переменная, но работает как таблица. Он также создан в базе данных Tempdb не в памяти. Переменная таблицы доступна только в области пакетной или хранимой процедуры. Вам не нужно удалять переменную таблицы, она автоматически удаляется при завершении процесса выполнения пакетной и хранимой процедуры

первичный ключ поддержки переменной таблицы, идентичность во время создания. Но он не поддерживает некластеризованный индекс. После объявления первичного ключа identity вы не можете их изменить.

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

прочитайте эту статью Для больше -http://goo.gl/GXtXqz