AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / user-47354

Michael B's questions

Martin Hope
Michael B
Asked: 2021-02-17 19:21:43 +0800 CST

Procedimentos usando TVPs são mais lentos quando o valor numérico de TVP fica maior?

  • 3

Um aplicativo legado tem um trabalho noturno que chama repetidamente algum procedimento de armazenamento usando um TVP e passa em lotes de 10.000 ids que estão em ordem sequencial que ele precisa processar. Agora que os IDs estão na casa dos milhões, parece que esse processo está demorando visivelmente mais. Quase o mesmo número de chamadas em lote está sendo executado todas as noites, mas pelo perfil parecia que o procedimento estava ficando mais lento. Verificamos os culpados usuais, reconstruímos os índices e atualizamos as estatísticas nas tabelas em uso e tentamos fazer uma recompilação no procedimento. Mas nada corrigiu a regressão.

O procedimento faz algum processamento e retorna alguns resultados, cada um com uma cardinalidade de talvez 10.000 linhas. Um dos meus colegas olhou para ele e corrigiu a regressão de desempenho atualizando o procedimento de armazenamento simplesmente adicionando o seguinte ao topo da consulta:

select id into #t from @ids

e substituindo todos os usos de @idspor #t.

Fiquei impressionado com essa correção simples e estava tentando entendê-la mais. Tentei criar uma reprodução muito simples.

create table dbo.ids
(
   id int primary key clustered,
   timestamp
);

create type dbo.tvp as table(id int primary key clustered)

insert into dbo.ids(id)
select row_number() over (order by 1/0)
from string_split(space(1414),' ') a,string_split(space(1414),' ') b
go
create or alter procedure dbo.tvp_proc
(
    @ids dbo.tvp readonly
)
as
begin
    declare @_ int = 0, @r int = 5;
    while(@r > 0)
        select @_ = count(*), @r -= 1
        from dbo.ids i
        where exists (
            select 1
            from @ids t
            where t.id = i.id     
        );
end 
go
create or alter procedure dbo.temp_proc
(
    @ids dbo.tvp readonly
)
as
begin
    select * into #t from @ids
    declare @_ int = 0, @r int = 5;
    while(@r > 0)
        select @_ = count(*), @r -= 1
        from dbo.ids i
        where exists (
            select 1
            from #t t
            where t.id = i.id     
        );
end

E aqui está o meu benchmark simples.

set nocount on;
declare @s nvarchar(4000)=
'declare @ids tvp;
insert into @ids(id)
select @init + row_number() over (order by 1/0)
from string_split(space(99),char(32)) a,string_split(space(99),char(32)) b
declare @s datetime2 = sysutcdatetime()
create table #d(_ int)
insert into #d
exec dbo.tvp_proc @ids
print concat(right(concat(space(10),format(@init,''N0'')),10),char(9),datediff(ms, @s, sysutcdatetime()))',
@params nvarchar(20)=N'@init int'
print 'tvp result'
exec sp_executesql @s,@params,10000000
exec sp_executesql @s,@params,1000000
exec sp_executesql @s,@params,100000
exec sp_executesql @s,@params,10000
select @s=replace(@s,'tvp_proc','temp_proc')
print 'temp table result'
exec sp_executesql @s,@params,10000000
exec sp_executesql @s,@params,1000000
exec sp_executesql @s,@params,100000
exec sp_executesql @s,@params,10000

A execução deste benchmark na minha máquina produz os seguintes resultados:

tvp result
10,000,000  653
 1,000,000  341
   100,000  42
    10,000  12
temp table result
10,000,000  52
 1,000,000  60
   100,000  57
    10,000  59

Os resultados mostram que a abordagem tvp parece desacelerar à medida que os ids internos aumentam, enquanto a tabela temporária permanece bastante consistente. Alguém tem uma idéia de por que referenciar um tvp com valores maiores é mais lento que uma tabela temporária?

sql-server-2016 table-valued-parameters
  • 1 respostas
  • 288 Views
Martin Hope
Michael B
Asked: 2019-08-07 10:57:46 +0800 CST

Como posso detectar o que está mudando minhas configurações de escopo?

  • 4

Estou percebendo que tenho um banco de dados que continua redefinindo a configuração do escopo, ou seja, maxdop.

Existe algum log que mostre quem ou qual processo está causando essas alterações de configuração? Estou no Microsoft SQL Server 2016 (SP1-CU7-GDR) (KB4057119) - 13.0.4466.4

sql-server sql-server-2016
  • 1 respostas
  • 94 Views
Martin Hope
Michael B
Asked: 2019-06-15 06:33:22 +0800 CST

Como forço o SQL Server a usar meu índice espacial por meio de uma exibição?

  • 6

Eu tenho tabelas que contém transações para propriedades que são armazenadas como pares long long. (Existem mais colunas e pontos de dados do que no meu esquema de exemplo).

Uma solicitação comum é encontrar as transações que aconteceram a X milhas de um determinado ponto e recuperar apenas as 5 transações mais recentes que aconteceram para cada propriedade próxima.

Para fazer isso funcionar, decidi adicionar uma visão que encapsula essa lógica das mais recentes:

create or alter view dbo.v_example
with schemabinding as
select example_id
      ,transaction_dt
      ,latitude
      ,longitude
      ,latlong
      ,most_recent= iif(row_number() over (partition by latitude,longitude order by transaction_dt desc) < 5,1,null)
from dbo.example;

Portanto, uma consulta pode ser assim::

select *
from dbo.v_example
where latlong.STDistance(geography::Point(40,-74,4326)) <=1609.344e1
and most_recent = 1

Infelizmente, o SQL Server não quer usar o índice espacial quando eu consulto pela view. Se eu remover schemabindinge tentar adicionar uma dica na exibição, recebo que o processador de consultas não pode criar um plano.

Como posso encapsular a lógica e ainda fazer com que ela use meu índice espacial?

Aqui está um db<>fiddle com dados de exemplo e formas de plano .

A tabela é muito maior e é muito mais lento varrê-la do que fazer uma busca de índice clusterizado e, em seguida, encontrar o ponto próximo.

sql-server sql-server-2016
  • 1 respostas
  • 437 Views
Martin Hope
Michael B
Asked: 2019-05-03 06:13:46 +0800 CST

Por que essa tabela derivada melhora o desempenho?

  • 18

Eu tenho uma consulta que leva uma string json como parâmetro. O json é uma matriz de pares de latitude e longitude. Um exemplo de entrada pode ser o seguinte.

declare @json nvarchar(max)= N'[[40.7592024,-73.9771259],[40.7126492,-74.0120867]
,[41.8662374,-87.6908788],[37.784873,-122.4056546]]';

Ele chama um TVF que calcula o número de POIs em torno de um ponto geográfico, a distâncias de 1,3,5,10 milhas.

create or alter function [dbo].[fn_poi_in_dist](@geo geography)
returns table
with schemabinding as
return 
select count_1  = sum(iif(LatLong.STDistance(@geo) <= 1609.344e * 1,1,0e))
      ,count_3  = sum(iif(LatLong.STDistance(@geo) <= 1609.344e * 3,1,0e))
      ,count_5  = sum(iif(LatLong.STDistance(@geo) <= 1609.344e * 5,1,0e))
      ,count_10 = count(*)
from dbo.point_of_interest
where LatLong.STDistance(@geo) <= 1609.344e * 10

A intenção da consulta json é chamar essa função em massa. Se eu chamar assim o desempenho é muito ruim levando quase 10 segundos para apenas 4 pontos:

select row=[key]
      ,count_1
      ,count_3
      ,count_5
      ,count_10
from openjson(@json)
cross apply dbo.fn_poi_in_dist(
            geography::Point(
                convert(float,json_value(value,'$[0]'))
               ,convert(float,json_value(value,'$[1]'))
               ,4326))

plano = https://www.brentozar.com/pastetheplan/?id=HJDCYd_o4

No entanto, mover a construção da geografia dentro de uma tabela derivada faz com que o desempenho melhore drasticamente, concluindo a consulta em cerca de 1 segundo.

select row=[key]
      ,count_1
      ,count_3
      ,count_5
      ,count_10
from (
select [key]
      ,geo = geography::Point(
                convert(float,json_value(value,'$[0]'))
               ,convert(float,json_value(value,'$[1]'))
               ,4326)
from openjson(@json)
) a
cross apply dbo.fn_poi_in_dist(geo)

plano = https://www.brentozar.com/pastetheplan/?id=HkSS5_OoE

Os planos parecem praticamente idênticos. Nenhum usa paralelismo e ambos usam o índice espacial. Há um carretel preguiçoso adicional no plano lento que posso eliminar com a dica option(no_performance_spool). Mas o desempenho da consulta não muda. Ainda continua muito mais lento.

A execução de ambos com a dica adicionada em um lote pesará as duas consultas igualmente.

Versão do servidor SQL = Microsoft SQL Server 2016 (SP1-CU7-GDR) (KB4057119) - 13.0.4466.4 (X64)

Então minha pergunta é por que isso importa? Como posso saber quando devo calcular valores dentro de uma tabela derivada ou não?

sql-server sql-server-2016
  • 1 respostas
  • 1972 Views
Martin Hope
Michael B
Asked: 2014-09-13 09:40:31 +0800 CST

Acessar conflitos de gravação com exibições e gatilhos em vez de?

  • 0

Eu tenho uma tabela vinculada herdada em um banco de dados msaccess que está vinculado a uma tabela sql-server.

A tabela vinculada está sendo sincronizada periodicamente com um conjunto diferente de tabelas que foram divididas por vários motivos e possuem mais colunas do que os usuários desejam ver. Eu gostaria de me livrar da tabela herdada e das dores de cabeça de sincronizá-la, criando uma visualização em vez de gatilhos para lidar com o acesso aos dados. Digamos que minha visão se pareça com:

Create view Compatibility_View
with schemabinding,view_metadata
as
select   a.Name,a.col_1 aliasedName,a.col_2 aliasedName2
        ,b.col_1 aliasNamed3 ,convert(float,b.col_2) aliasedName4
        ,a.modified_date,a.modified_by
from dbo.some a
join dbo.other b
  on a.some_Id = b.some_Id
where a.isActive = 1;

E eu tenho, em vez de gatilhos, que excluirão os registros e encaminharão as propriedades adequadamente.

Eu também atualizo automaticamente as colunas modify_date e modify_by. (Eles costumam ser manipulados por gatilhos posteriores na tabela legada).

Infelizmente, fazer esse segundo conjunto de requisitos faz com que o acesso emita um aviso após cada edição de que os dados foram alterados. Rastreando os problemas de acesso às consultas, parece que está fazendo uma atualização na exibição, certificando-se de que todas as outras colunas não foram alteradas. por exemplo

update "dbo"."Compatibility_View"
set "aliasedName"='v'
where "aliasedName2"=45 and "aliasedName3"='horse'
and "aliasedName4"=1.3e2 and "modified_date"='09/10/2014 12:35:00.00'
and "modified_by"='AD\SomeUser'

Como meu gatilho altera o acesso às colunas modified_datee o modifed_byvisualiza como uma discrepância e envia um prompt de erro feio?

Os usuários gostam de ver as colunas modified_datee modified_byno acesso, então remover esta parte não é realmente uma opção. Como posso obter essas colunas na exibição sem que o acesso surte?

sql-server ms-access
  • 1 respostas
  • 236 Views

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve