В чем разница между временной таблицей и табличной переменной в 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 также имеет неуникальные индексы.
табличные переменные не участвуют в сделках и
SELECT
s неявно сNOLOCK
. Поведение транзакции может быть очень полезно, например, если вы хотите откатиться на полпути через процедуру, то переменные таблицы, заполненные во время этой транзакции, все равно будут заполнены!временные таблицы могут привести к перекомпиляции хранимых процедур, возможно, часто. Табличные переменные не будут.
вы можете создать временную таблицу с помощью SELECT INTO, что может быть быстрее для записи (хорошо для специальных запросов) и может позволить вам иметь дело с изменением типов данных с течением времени, так как вам не нужно заранее определять структуру временной таблицы.
вы можете передавать табличные переменные обратно из функций, что позволяет инкапсулировать и повторно использовать логику намного проще (например, сделать функцию для разделения строки в таблицу значения на некотором произвольном разделителе).
использование табличных переменных в пользовательских функциях позволяет использовать эти функции более широко (Подробнее см. раздел создание документации по функциям). Если вы пишете функцию, вы должны использовать табличные переменные над временными таблицами, если нет настоятельной необходимости в противном случае.
как табличные переменные и временные таблицы хранятся в базе данных tempdb. Но табличные переменные (с 2005 года) по умолчанию для сортировки текущая база данных и временные таблицы, которые принимают параметры сортировки tempdb по умолчанию ( ref). Это означает, что вы должны знать о проблемах сортировки при использовании временных таблиц, и ваши параметры сортировки БД отличаются от tempdb, что вызывает проблемы, если вы хотите сравнить данные в временной таблице с данными в вашей базе данных.
глобальные временные таблицы (##tmp) - это еще один тип временных таблиц, доступных для всех сеансов и пользователей.
еще немного чтение:
отличный ответ Мартина Смита on dba.stackexchange.com
часто задаваемые вопросы MSDN на разницу между двумя: https://support.microsoft.com/en-gb/kb/305977
статья блога MDSN: http://blogs.msdn.com/sqlserverstorageengine/archive/2008/03/30/sql-server-table-variable-vs-local-temporary-table.aspx
статьи: http://searchsqlserver.techtarget.com/tip/0,289483,sid87_gci1267047,00.html#
неожиданное поведение и влияние на производительность временных таблиц и переменных temp: Пол Уайт включен SQLblog.com
просто глядя на утверждение в принятом ответе, что переменные таблицы не участвуют в регистрации.
кажется вообще неверным, что есть какая-то разница в количестве регистрации (по крайней мере для
insert
/update
/delete
операции с самой таблицей, хотя у меня есть С что существует небольшая разница в этом отношении для кэшированных временных объектов в хранимых процедурах из-за дополнительных обновлений системных таблиц).Я посмотрел на протоколирование поведения в отношении как
@table_variable
и#temp
таблица для следующих операций.
- Удачный Вставить
- Многорядная вставка, где оператор откатывается из-за нарушения ограничений.
- обновление
- удалить
- освободить
записи журнала транзакций были почти идентичны для всех операций.
версия переменной таблицы на самом деле имеет несколько дополнительно записи журнала, потому что он получает запись, добавленную (а затем удаленную) в
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 строк) используйте временную переменную, в противном случае используйте временную таблицу.
@wcm-на самом деле, чтобы NIT выбрать переменную таблицы не только ОЗУ - она может быть частично сохранена на диске.
временная таблица может иметь индексы, тогда как табличная переменная может иметь только первичный индекс. Если скорость-это переменные таблицы проблем, которые могут быть быстрее, но, очевидно, если есть много записей или необходимость поиска временной таблицы кластеризованного индекса, то временная таблица будет лучше.
временная таблица: временная таблица проста в создании и резервном копировании данных.
переменная таблицы: но переменная таблицы включает в себя усилия, когда мы обычно создаем обычные таблицы.
таблица Temp: результат таблицы Temp может быть использован несколькими пользователями.
переменная таблицы: но переменная таблицы может использоваться только текущим пользователем.
временная таблица: временная таблица будет храниться в базе данных tempdb. Это сделает сетевой трафик. Когда у нас есть большие данные в временную таблицу, то он должен работать по всей базе. Проблема производительности будет существовать.
переменная таблицы: но переменная таблицы будет храниться в физической памяти для некоторых данных, а затем, когда размер увеличивается, она будет перемещена в базу данных tempdb.
временная таблица: временная таблица может выполнять все операции DDL. Это позволяет создать индексы, падать, изменять и т. д..,
переменная таблицы: тогда как табличная переменная не позволит выполнять операции DDL. Но табличная переменная позволяет нам создавать только кластеризованный индекс.
временная таблица: временная таблица может использоваться для текущей сессии или глобальной. Так что сеанс нескольких пользователей может использовать результаты в таблице.
переменная таблицы: но переменная таблицы может быть использована до этой программы. (Хранимая процедура)
таблица Temp: переменная Temp не может использовать транзакции. Когда мы делаем операции DML с временной таблицей, тогда это может быть откат или фиксация транзакций.
переменная таблицы: но мы не можем сделать это для переменной таблицы.
таблица Temp: функции не могут использовать переменную temp. Более того, мы не можем выполнять операцию DML в функциях .
табличная переменная: но функция позволяет нам использовать табличную переменную. Но с помощью табличной переменной мы можем это сделать.
временные таблицы: хранимая процедура будет выполнять перекомпиляцию (не может использовать один и тот же план выполнения), когда мы используем переменную temp для каждого вызова sub sequent.
переменной: если переменная не нравится.
для всех вас, кто верит мифу, что временные переменные находятся только в памяти
во-первых, переменная таблицы не обязательно является резидентной памятью. Под давлением памяти страницы, принадлежащие табличной переменной, могут быть вытеснены в базу данных tempdb.
Читать статью здесь: TempDB:: переменная таблицы vs локальная временная таблица
другое основное различие заключается в том, что табличные переменные не имеют статистики столбцов, где, как и временные таблицы. Это означает, что оптимизатор запросов не знает, сколько строк находится в табличной переменной (он предполагает 1), что может привести к созданию крайне неоптимальных планов, если табличная переменная действительно имеет большое количество строк.
цитата взята из; профессиональные внутренние компоненты SQL Server 2012 и устранение неполадок
статистика Основное различие между временными таблицами и табличными переменными заключается в том, что статистика не создается по табличным переменным. Это имеет два основных последствий, первым из которых является то, что оптимизатор запросов использует фиксированная оценка количества строк в табличной переменной независимо от содержащихся в нем данных. Кроме того, добавление или удаление данные не изменяют оценку.
индексы вы не можете создавать индексы для табличных переменных, хотя можете создание ограничений. Это означает, что путем создания первичных ключей или уникальных ограничения, вы можете иметь индексы (так как они создаются для поддержки ограничения) на табличные переменные. Даже если у вас есть ограничения, и поэтому индексы, которые будут иметь статистику, индексами не будут используется при компиляции, потому что они не существуют в компилировать время, и они не будут вызывать перекомпиляции.
Модификации Схемы изменения схемы возможны на временной основе таблицы, но не по табличным переменным. Хотя модификации схемы являются возможно на временных таблицах, избегайте их использования, потому что они вызывают перекомпиляция операторов, использующих таблицы.
ТАБЛИЧНЫЕ ПЕРЕМЕННЫЕ НЕ СОЗДАЮТСЯ В ПАМЯТИ
есть распространенное заблуждение, что табличные переменные хранятся в памяти и как таковой будет выполнять быстрее, чем временные таблицы. Благодаря DMV называется сис . dm _ db _ session _ space _ usage, который показывает использование базы данных tempdb сессия,вы можете доказать, что это не так. После перезагрузки SQL Server, чтобы очистить DMV, запустите следующий скрипт для подтверждения того, что ваш сеанс _ id возвращает 0 для пользователь _ объекты _ выделено _ страница _ графа :
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. Теперь запустите тот же скрипт, но используйте переменную таблицы на этот раз:
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 не в памяти. Табличная переменная доступна только в области пакета или хранимой процедуры. Вам не нужно удалять переменную таблицы , она автоматически удаляется при завершении процесса выполнения пакетной и хранимой процедуры
первичный ключ поддержки переменной таблицы, идентичность во время создания. Но он не поддерживает некластеризованный индекс. После объявления первичного ключа, удостоверения вы не можете их изменить.
табличные переменные не участвуют в транзакциях, регистрации или блокировке. Транзакции, ведение журнала и блокировка не влияют на переменные таблицы.
прочитайте эту статью Подробнее -http://goo.gl/GXtXqz