Preciso ler dados de um servidor vinculado e inserir em uma tabela local. Preciso remover duplicatas nos dados e preciso fazer isso em um servidor local, pois o servidor remoto está sobrecarregado. Então, eu adicionei uma DISTINCT
cláusula que faz Distinct Sort como eu quero.
O problema é que o operador Remote Scan sempre estima o número de linhas como 10.000, enquanto o número real de linhas é em torno de 3M. Assim, a classificação se espalha para o disco e se torna lenta.
Se existe uma maneira de sugerir ao otimizador que o número real de linhas é muito maior que 10K?
Devo carregar dados brutos em uma tabela de preparo local e, em seguida, executar DISTINCT na tabela local? Eu não queria gravar no disco duas vezes.
O número de linhas duplicadas é pequeno - algumas centenas de 3M. Quero dizer com isso que antes que as duplicatas sejam removidas, existem ~ 3.000.000 linhas; depois que os duplicados são removidos, existem cerca de 2.999.800 linhas. Portanto, remover as duplicatas no servidor remoto não reduziria visivelmente a quantidade de dados transferidos pela rede.
A tabela de destino é truncada antes da inserção, então estou sempre inserindo em uma tabela vazia. Além disso, a tabela de destino não possui índices, gatilhos ou restrições. Há muitas colunas na tabela. Cerca de 110 colunas. Na consulta abaixo, escrevi ManyManyColumns
em vez disso.
A pergunta:
WITH
CTE_Raw
AS
(
SELECT
[ManyManyColumns]
FROM OpenQuery([remote_server],'
SELECT
[ManyManyColumns]
FROM
[DB].[dbo].[remote_view]
')
)
,CTE_Converted
AS
(
SELECT DISTINCT
[ManyManyColumns]
FROM
CTE_Raw
)
INSERT INTO [dbo].[TestVBFast2]
([ManyManyColumns]
)
SELECT
[ManyManyColumns]
FROM
CTE_Converted
;
Versão do SQL Server:
Microsoft SQL Server 2012 (SP4) (KB4018073) - 11.0.7001.0 (X64) 15 de agosto de 2017 10:23:29 Direitos autorais (c) Microsoft Corporation Standard Edition (64 bits) no Windows NT 6.3 (Build 9600: ) (Hypervisor)
Quero realizar o DISTINCT
localmente, pois o servidor remoto está sobrecarregado e quero reduzir sua carga. DISTINCT
removerá apenas algumas centenas de linhas da 3M, portanto, a quantidade de dados transferidos pela rede não mudará muito.
Minha sugestão é mudar para pacotes SSIS que possam lidar com isso de uma maneira melhor, com buffers na origem e no destino, mais rápido que os servidores vinculados.
Por favor, dê uma olhada nisso:
https://social.technet.microsoft.com/wiki/contents/articles/30703.ssis-implementing-a-faster-distinct-sort-or-aggregate-transformation.aspx
Suponho que ManyManyColumns seja realmente várias colunas e não uma coluna?... Vejo que seu comentário afirma que é 110 na verdade.
10.000 linhas é a estimativa de cardinalidade padrão para uma operação Remote Scan em sua versão do SQL Server, então não acho que você possa fazer muito para mudar isso, infelizmente.
Quão lento é lento atualmente? Tenha em mente que, mesmo com estimativas de cardinalidade perfeitamente precisas , 3 milhões de linhas sempre serão muitos dados para canalizar pela rede/ servidor vinculado , especialmente se você tiver muitas colunas.
As únicas idéias gerais que tenho no momento são pré-preparar os
DISTINCT
dados em seu servidor remoto ou usar um recurso de sincronização de dados como replicação para copiá-los para seu servidor local em vez de usar um servidor vinculado . Se eu pensar em mais alguma coisa, atualizarei minha resposta de acordo.