Essa diferença parece se aplicar apenas quando o objeto é uma árvore B +. Ao remover a primary keyvariável on the table, por isso é uma pilha, obtive os seguintes resultados
2560
2120
2080
2130
2140
Mas com o PK, encontrei um padrão semelhante nos meus testes, bem como com os resultados típicos abaixo.
+--------+--------+---------+-------------------+
| @table | #table | ##table | [permanent_table] |
+--------+--------+---------+-------------------+
| 2670 | 2683 | 9603 | 9703 |
| 6823 | 6840 | 9723 | 9790 |
| 6813 | 6816 | 9626 | 9703 |
| 6883 | 6816 | 9600 | 9716 |
| 6840 | 6856 | 9610 | 9673 |
+--------+--------+---------+-------------------+
Minha teoria é que existe alguma otimização disponível ao fazer inserções em massa em árvores B + temporárias locais que só se aplicam quando ainda não há nenhuma página alocada.
Baseamos isso nas seguintes observações.
Ao executar várias versões do seu código de teste, vi apenas esse padrão com @table_variablese #temptabelas. Tabelas não permanentes tempdbnem ##tabelas.
Para obter um desempenho mais lento, não é necessário adicionar e remover anteriormente uma grande quantidade de linhas da tabela. Basta adicionar uma única linha e deixá-la lá é suficiente.
TRUNCATEdesaloca todas as páginas da tabela. DELETEnão fará com que a última página da tabela seja desalocada.
O uso do criador de perfil do VS 2012 mostra que, no caso mais rápido, o SQL Server usa um caminho de código diferente. 36% do tempo é gasto sqlmin.dll!RowsetBulk::InsertRowcontra 61% do tempo gasto no sqlmin.dll!RowsetNewSS::InsertRowcaso mais lento.
Corrida
SELECT *
FROM sys.dm_db_index_physical_stats(2,OBJECT_ID('tempdb..#values'),1,NULL, 'DETAILED')
após a exclusão retornar
+-------------+------------+--------------+--------------------+
| index_level | page_count | record_count | ghost_record_count |
+-------------+------------+--------------+--------------------+
| 0 | 1 | 0 | 1 |
| 1 | 1 | 1 | 0 |
| 2 | 1 | 1 | 0 |
+-------------+------------+--------------+--------------------+
Descobri que era possível reduzir a discrepância de tempo, ativando o sinalizador de rastreamento 610 .
Isto teve o efeito de reduzir a quantidade de log substancialmente para as inserções subsequentes (para baixo de 350 MB de 103 MB, uma vez que não regista os valores de linha inseridos individuais), mas este teve apenas uma pequena melhoria na temporizações para o segundo e subsequentes @table, #tablecasos e a diferença ainda permanece. O sinalizador de rastreamento melhorou significativamente o desempenho geral das inserções nos outros dois tipos de tabela.
+--------+--------+---------+-------------------+
| @table | #table | ##table | [permanent_table] |
+--------+--------+---------+-------------------+
| 2663 | 2670 | 5403 | 5426 |
| 5390 | 5396 | 5410 | 5403 |
| 5373 | 5390 | 5410 | 5403 |
| 5393 | 5410 | 5406 | 5433 |
| 5386 | 5396 | 5390 | 5420 |
+--------+--------+---------+-------------------+
Observando o log de transações, notei que as inserções iniciais em tabelas temporárias locais vazias parecem ainda mais minimamente registradas (em 96 MB).
Notavelmente, essas inserções mais rápidas tiveram apenas 657transações ( LOP_BEGIN_XACT/ LOP_COMMIT_XACTpares) comparadas com mais 10,000nos casos mais lentos. Em particular, as LOP_FORMAT_PAGEoperações parecem muito reduzidas. Os casos mais lentos têm uma entrada no log de transações para cada página da tabela (aproximadamente 10,270) em comparação com apenas4 essas entradas no caso rápido.
O log usado nos três casos foi o seguinte (eu excluí os registros de atualizações das tabelas base do sistema para reduzir a quantidade de texto, mas eles ainda estão incluídos nos totais)
Primeira inserção de logon @table_var(96,5 MB)
+-----------------------+----------+----------------------------------------------+---------------+---------+
| Operation | Context | AllocUnitName | Size in Bytes | Cnt |
+-----------------------+----------+----------------------------------------------+---------------+---------+
| LOP_BEGIN_XACT | LCX_NULL | NULL | 83876 | 658 |
| LOP_COMMIT_XACT | LCX_NULL | NULL | 34164 | 657 |
| LOP_CREATE_ALLOCCHAIN | LCX_NULL | NULL | 120 | 3 |
| LOP_FORMAT_PAGE | LCX_HEAP | dbo.#531856C7 | 84 | 1 |
| LOP_FORMAT_PAGE | LCX_IAM | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 84 | 1 |
| LOP_FORMAT_PAGE | LCX_IAM | dbo.#531856C7 | 84 | 1 |
| LOP_FORMAT_PAGE | LCX_IAM | Unknown Alloc Unit | 84 | 1 |
| LOP_HOBT_DDL | LCX_NULL | NULL | 216 | 6 |
| LOP_HOBT_DELTA | LCX_NULL | NULL | 320 | 5 |
| LOP_IDENT_NEWVAL | LCX_NULL | NULL | 100240000 | 2506000 |
| LOP_INSERT_ROWS | LCX_HEAP | dbo.#531856C7 | 72 | 1 |
| LOP_MODIFY_ROW | LCX_IAM | dbo.#531856C7 | 88 | 1 |
| LOP_MODIFY_ROW | LCX_PFS | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 158592 | 1848 |
| LOP_MODIFY_ROW | LCX_PFS | dbo.#531856C7 | 80 | 1 |
| LOP_MODIFY_ROW | LCX_PFS | Unknown Alloc Unit | 216016 | 2455 |
| LOP_SET_BITS | LCX_GAM | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 84360 | 1406 |
| LOP_SET_BITS | LCX_GAM | Unknown Alloc Unit | 147120 | 2452 |
| LOP_SET_BITS | LCX_IAM | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 84360 | 1406 |
| LOP_SET_BITS | LCX_IAM | Unknown Alloc Unit | 147120 | 2452 |
| Total | NULL | NULL | 101209792 | 2519475 |
+-----------------------+----------+----------------------------------------------+---------------+---------+
Log de inserções subseqüentes TF 610 desativado (350 MB)
+-----------------------+--------------------+----------------------------------------------+---------------+---------+
| Operation | Context | AllocUnitName | Size in Bytes | Cnt |
+-----------------------+--------------------+----------------------------------------------+---------------+---------+
| LOP_BEGIN_CKPT | LCX_NULL | NULL | 96 | 1 |
| LOP_BEGIN_XACT | LCX_NULL | NULL | 1520696 | 12521 |
| LOP_COMMIT_XACT | LCX_NULL | NULL | 651040 | 12520 |
| LOP_CREATE_ALLOCCHAIN | LCX_NULL | NULL | 40 | 1 |
| LOP_DELETE_SPLIT | LCX_INDEX_INTERIOR | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 2160 | 36 |
| LOP_END_CKPT | LCX_NULL | NULL | 136 | 1 |
| LOP_FORMAT_PAGE | LCX_HEAP | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 859236 | 10229 |
| LOP_FORMAT_PAGE | LCX_IAM | Unknown Alloc Unit | 84 | 1 |
| LOP_FORMAT_PAGE | LCX_INDEX_INTERIOR | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 3108 | 37 |
| LOP_HOBT_DDL | LCX_NULL | NULL | 648 | 18 |
| LOP_HOBT_DELTA | LCX_NULL | NULL | 657088 | 10267 |
| LOP_IDENT_NEWVAL | LCX_NULL | NULL | 100239960 | 2505999 |
| LOP_INSERT_ROWS | LCX_CLUSTERED | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 258628000 | 2506000 |
| LOP_INSERT_ROWS | LCX_HEAP | dbo.#531856C7 | 72 | 1 |
| LOP_INSERT_ROWS | LCX_INDEX_INTERIOR | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 1042776 | 10302 |
| LOP_MODIFY_HEADER | LCX_HEAP | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 859236 | 10229 |
| LOP_MODIFY_HEADER | LCX_INDEX_INTERIOR | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 3192 | 38 |
| LOP_MODIFY_ROW | LCX_IAM | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 704 | 8 |
| LOP_MODIFY_ROW | LCX_PFS | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 934264 | 11550 |
| LOP_MODIFY_ROW | LCX_PFS | Unknown Alloc Unit | 783984 | 8909 |
| LOP_SET_BITS | LCX_GAM | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 76980 | 1283 |
| LOP_SET_BITS | LCX_GAM | Unknown Alloc Unit | 534480 | 8908 |
| LOP_SET_BITS | LCX_IAM | dbo.#4F47C5E3.PK__#4F47C5E__3213E83F51300E55 | 76980 | 1283 |
| LOP_SET_BITS | LCX_IAM | Unknown Alloc Unit | 534480 | 8908 |
| LOP_SHRINK_NOOP | LCX_NULL | NULL | 32 | 1 |
| LOP_XACT_CKPT | LCX_NULL | NULL | 92 | 1 |
| Total | NULL | NULL | 367438748 | 5119297 |
+-----------------------+--------------------+----------------------------------------------+---------------+---------+
Registrar inserções subseqüentes TF 610 on (103 MB)
+-------------------------+-------------------------+----------------------------------------------+---------------+---------+
| Operation | Context | AllocUnitName | Size in Bytes | Cnt |
+-------------------------+-------------------------+----------------------------------------------+---------------+---------+
| LOP_BEGIN_CKPT | LCX_NULL | NULL | 192 | 2 |
| LOP_BEGIN_XACT | LCX_NULL | NULL | 1339796 | 11099 |
| LOP_BULK_EXT_ALLOCATION | LCX_NULL | NULL | 20616 | 162 |
| LOP_COMMIT_XACT | LCX_NULL | NULL | 577096 | 11098 |
| LOP_CREATE_ALLOCCHAIN | LCX_NULL | NULL | 40 | 1 |
| LOP_DELETE_SPLIT | LCX_INDEX_INTERIOR | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 2160 | 36 |
| LOP_END_CKPT | LCX_NULL | NULL | 272 | 2 |
| LOP_FORMAT_PAGE | LCX_BULK_OPERATION_PAGE | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 863520 | 10280 |
| LOP_FORMAT_PAGE | LCX_IAM | Unknown Alloc Unit | 84 | 1 |
| LOP_FORMAT_PAGE | LCX_INDEX_INTERIOR | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 3108 | 37 |
| LOP_HOBT_DELTA | LCX_NULL | NULL | 666496 | 10414 |
| LOP_IDENT_NEWVAL | LCX_NULL | NULL | 100239960 | 2505999 |
| LOP_INSERT_ROWS | LCX_CLUSTERED | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 23544 | 218 |
| LOP_INSERT_ROWS | LCX_HEAP | dbo.#719CDDE7 | 72 | 1 |
| LOP_INSERT_ROWS | LCX_INDEX_INTERIOR | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 1042776 | 10302 |
| LOP_MODIFY_HEADER | LCX_BULK_OPERATION_PAGE | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 780216 | 10266 |
| LOP_MODIFY_HEADER | LCX_HEAP | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 1718472 | 20458 |
| LOP_MODIFY_HEADER | LCX_INDEX_INTERIOR | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 3192 | 38 |
| LOP_MODIFY_ROW | LCX_IAM | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 704 | 8 |
| LOP_MODIFY_ROW | LCX_PFS | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 114832 | 1307 |
| LOP_MODIFY_ROW | LCX_PFS | Unknown Alloc Unit | 231696 | 2633 |
| LOP_RANGE_INSERT | LCX_NULL | NULL | 48 | 1 |
| LOP_SET_BITS | LCX_GAM | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 77100 | 1285 |
| LOP_SET_BITS | LCX_GAM | Unknown Alloc Unit | 157920 | 2632 |
| LOP_SET_BITS | LCX_IAM | dbo.#6DCC4D03.PK__#6DCC4D0__3213E83F6FB49575 | 77100 | 1285 |
| LOP_SET_BITS | LCX_IAM | Unknown Alloc Unit | 157920 | 2632 |
| LOP_XACT_CKPT | LCX_NULL | NULL | 92 | 1 |
| Total | NULL | NULL | 108102960 | 2602218 |
+-------------------------+-------------------------+----------------------------------------------+---------------+---------+