Tenho uma lista de 3.000 strings e as estou passando (vinte por vez) para uma cláusula IN parametrizada. Definitivamente não está obtendo os resultados que eu gostaria de ver ~ 500ms por execução.
A coluna é um índice. Você conhece uma maneira melhor do que esta:
SELECT * FROM [ohb].[dbo].[MasterUrls] WITH (NOLOCK) WHERE Hash
IN(@p0,@p1,@p2,@p3,@p4,@p5,@p6,@p7,@p8,@p9,@p10,@p11,@p12,@p13,@p14,@p15,@p16,@p17,@p18,@p19)
Uma lista de 3000 leva entre 3 e 5 minutos. Eu realmente preciso disso para cerca de 30 segundos. Isso é possível?
Estou usando o MSSQL 2008 R2 em um servidor com 24 GB de RAM e NUMA Xeons duplos de 8 núcleos a 2,4 Ghz rodando em um RAID 10 ISCSI de 6 HDD (@15k/rpm).
A tabela tem 1,4 milhão de linhas e o índice é um índice não clusterizado.
O plano de execução mostra a varredura de índice como 90% da execução total.
SELECT *
invalidará qualquer uso ideal de um índice (não está cobrindo), mesmo que o hash seja indexado. Sua varredura de índice provavelmente está no índice clusterizado por causa disso.Pessoalmente, eu começaria com
Algo como
Passe os valores por meio de um parâmetro de valor de tabela. Desta forma, eles já estão em forma de tabela. Em seguida, copie os valores do TVP para uma tabela temporária, que contém um índice clusterizado. Use esta tabela temporária como um membro JOIN de sua consulta.
Remova o SELECT * e altere-o para apenas as colunas necessárias, com as colunas adicionais incluídas. Se SELECT * for necessário, inclua todas as colunas adicionais como colunas incluídas no índice.
Sim: - Isso é possível, basta armazenar todos os id de passagem em uma string com valor separado por vírgula e fazer uma função:
Basta seguir o passo:
Primeiro faça uma função:
depois disso, basta usar com junção interna: -
Na verdade, resolvi isso de uma maneira MUITO mais rápida e sem SQL.
Em outra etapa antes desta, pego as URLs e IDs da tabela (em vez de apenas a URL, que eu usaria como hash para a pesquisa - esta pergunta), salvo-as na memória e, em seguida, no FS (no caso de falha na memória -- assíncrono, é claro), quando chegou a hora de fazer a pesquisa, li dos meus dados armazenados na memória/FS.
O processo agora leva menos de 5 segundos em média para fazer uma pesquisa e atualizar (a etapa após esta pergunta) os dados de 3.000 linhas. Muito melhor do que 240 segundos em média.