É meu entendimento, com base em várias fontes (incluindo esta: https://techcommunity.microsoft.com/t5/sql-server/migrating-sap-workloads-to-sql-server-just-got-2-5x-faster /ba-p/384910 ) que o SQL Server Trace Flag 715 deve ser equivalente à dica de consulta TABLOCK - com a diferença de que TF715 pode ser definido nos níveis de sessão e global, enquanto TABLOCK só pode ser usado como uma dica de consulta.
Meu problema é que testei no SQL Servers 2016 e 2019 Development Editions no modelo de recuperação simples e estou obtendo resultados diferentes entre o TABLOCK e o TF715, independentemente de qual servidor eu uso. O TABLOCK está funcionando conforme o esperado e o TF715 não. Especificamente, TABLOCK diz ao SQL Server para remover um bloqueio de tabela inteiro para operações em massa e registrar minimamente a operação .
Considere o código a seguir. Isso insere 10.000 linhas em um heap.
DROP TABLE IF EXISTS Test
GO
CREATE TABLE Test (t VARCHAR(100))
GO
INSERT INTO Test (t)
SELECT TOP (10000)
x = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.columns AS s1
CROSS JOIN sys.columns AS s2
Agora, se você executar este próximo bloco de código, poderá ver que ele registrou 10.000 linhas.
SELECT
[Fully Logged Rows] = COUNT_BIG(*)
FROM sys.fn_dblog(NULL, NULL) AS FD
WHERE
FD.Operation = N'LOP_INSERT_ROWS'
AND FD.Context = N'LCX_HEAP'
AND FD.AllocUnitName = N'dbo.Test';
Ok, agora se fizermos tudo de novo usando a dica TABLOCK, você verá que se torna uma operação minimamente registrada (ou seja, a contagem de linhas totalmente registrada = 0).
DROP TABLE IF EXISTS Test
GO
CREATE TABLE Test (t VARCHAR(100))
GO
INSERT INTO Test WITH (TABLOCK) (t)
SELECT TOP (10000)
x = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.columns AS s1
CROSS JOIN sys.columns AS s2
--0 Fully Logged Rows
SELECT
[Fully Logged Rows] = COUNT_BIG(*)
FROM sys.fn_dblog(NULL, NULL) AS FD
WHERE
FD.Operation = N'LOP_INSERT_ROWS'
AND FD.Context = N'LCX_HEAP'
AND FD.AllocUnitName = N'dbo.Test';
No entanto, quando tento habilitar o TF715 (e retirar a dica TABLOCK), ainda recebo 10.000 linhas totalmente registradas quando esperaria uma operação minimamente registrada.
--Enable TF715 on both a session and global level to cover all bases...
DBCC TRACEON(715)
GO
DBCC TRACEON(715, -1)
GO
DBCC TRACESTATUS
GO
DROP TABLE IF EXISTS Test
GO
CREATE TABLE Test (t VARCHAR(100))
GO
INSERT INTO Test (t)
SELECT TOP (10000)
x = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.columns AS s1
CROSS JOIN sys.columns AS s2
--10000 Fully Logged Rows
SELECT
[Fully Logged Rows] = COUNT_BIG(*)
FROM sys.fn_dblog(NULL, NULL) AS FD
WHERE
FD.Operation = N'LOP_INSERT_ROWS'
AND FD.Context = N'LCX_HEAP'
AND FD.AllocUnitName = N'dbo.Test';
DBCC TRACEOFF(715)
GO
DBCC TRACEOFF(715, -1)
GO
DBCC TRACESTATUS
GO
O que estou negligenciando? Eu não deveria precisar reiniciar o SQL Server para habilitar TFs por meio de DBCC, correto...?
Agradeço antecipadamente.
Uma citação importante do artigo referenciado por Parikshit Savjani (grifo nosso):
O sinalizador de rastreamento 715 habilita bloqueios de BU para métodos de carregamento em massa que suportam bloqueios de BU quando TABLOCK é especificado .
Todos os métodos de carregamento em massa suportam bloqueios de BU, exceto INSERT...SELECT .
Exemplos de outros métodos de carregamento em massa incluem:
Pode ser útil pensar no TF715 como fingindo que 'bloqueio de tabela no carregamento em massa' está sempre definido:
O TF 715 tem efeitos práticos semelhantes à especificação de TABLOCK em muitos casos, mas não é exatamente o mesmo. Em particular, os bloqueios de BU garantem que os processos de carregamento em massa tenham acesso exclusivo à tabela.
As otimizações de importação em massa são um conjunto de recursos. Você pode obter alguns dos benefícios, mas não outros em diferentes situações.
No seu exemplo, você não está recebendo bloqueios BU porque INSERT...SELECT não os suporta. O TF715 habilita apenas bloqueios de BU para métodos de carregamento em massa que suportam essa opção. TF715, portanto, não tem efeito no seu exemplo.
Quando você especifica TABLOCK, o mecanismo tem uma garantia aceitável de que a carga em massa tenha acesso exclusivo à tabela, portanto, o registro mínimo é permitido.
A discussão acima se aplica apenas a destinos de tabela de heap. O carregamento de uma tabela clusterizada pode se beneficiar do mesmo mecanismo subjacente ( RowsetBulk ) e também FastLoadContext , que não requer TABLOCK ou um bloqueio BU para habilitar o log mínimo.