Tenho que criar o DACPAC a partir do banco de dados de produção. Gostaria de fazer isso por meio do Visual Studio 2022 (SQL Server Object Explorer e "Extract - Data-tier application"). É possível bloquear algum processo/consulta ou utilizar mais CPU/memória para fazer isso?
Tenho os seguintes JSONs que gostaria de combinar. No meu JSON tenho a parte 'kenmerken' onde gostaria de adicionar mais alguns itens. Achei que isso poderia ser feito usando JSON_MODIFY. Porém quando eu uso o comando abaixo, ele irá substituir os itens 1, 2 e 3. E quando eu incluir 'append' antes de $.kenmerken, ele só mostrará os novos. Como posso conseguir ter ambos no objeto kenmerken?
DECLARE @FirstJSON NVARCHAR(MAX) = N'
{
"message id": "B673A8E4-3652-4544-A02D-BA9726BD71ED",
"volgnummer": 61000233530024,
"debug": null,
"kenmerken": {
"item 1": 1,
"item 2": 1,
"item 3": 1
}
}
';
DECLARE @KenmerkenToAdd NVARCHAR(MAX) = N'
{
"Item 4": false,
"Item 5": false
}
';
SET @FirstJSON = JSON_MODIFY(
@FirstJSON,
' $.kenmerken',
JSON_QUERY(@KenmerkenToAdd)
);
SELECT @FirstJSON;
Darei:
{
"message id": "B673A8E4-3652-4544-A02D-BA9726BD71ED",
"volgnummer": 61000233530024,
"debug": null,
"kenmerken": {
"Item 4": false,
"Item 5": false
}
}
Onde eu gostaria de ter:
{
"message id": "B673A8E4-3652-4544-A02D-BA9726BD71ED",
"volgnummer": 61000233530024,
"debug": null,
"kenmerken": {
"Item 1": 1,
"Item 2": 1,
"Item 3": 1,
"Item 4": false,
"Item 5": false
}
}
Estou coçando a cabeça, relendo a ajuda da MSFT e ainda não consigo entender a diferença entre forwarded_fetch_count e forwarded_record_count em sys.dm_db_index_operative_stats e sys.dm_db_index_physical_stats. Deixe-me ilustrar meu problema de compreensão dos pontos de vista com o exemplo abaixo.
Eu executei as seguintes consultas:
;with heaps as (
select
DB_NAME(DB_ID()) dbname, object_name ( p.object_id ) objname, sum(row_count) row_count,
DB_ID() database_id, p.object_id objectid
from
sys.dm_db_partition_stats p
join sys.objects o on o.object_id = p.object_id
WHERE
index_id = 0 and o.is_ms_shipped = 0 --and row_count > 0
group by p.object_id )
select
h.*,
forwarded_fetch_count
from heaps h
cross apply sys.dm_db_index_operational_stats(database_id, objectid, 0, null) ps
WHERE forwarded_fetch_count > 0 ORDER BY forwarded_fetch_count DESC¨
E
SELECT page_count, OBJECT_NAME(ps.object_id)
,avg_record_size_in_bytes
,avg_page_space_used_in_percent
,forwarded_record_count
FROM sys.dm_db_index_physical_stats(db_id('your_db_name'), NULL,NULL, NULL, 'DETAILED') AS ps
WHERE forwarded_record_count IS NOT NULL AND forwarded_record_count > 0
GO
Ambas as consultas retornaram listas diferentes de tabelas em um único banco de dados que estou ajustando. A primeira consulta retornou tabelas variando de 1.000 a 100.000 buscas encaminhadas por tabela, a segunda consulta retornou qualquer coisa entre 10 e 60.000 contagens de registros encaminhados para outro conjunto de tabelas.
Para consertar a fita adesiva, reconstruí as tabelas em questão. No entanto, no monitor de desempenho do Windows, ainda vejo muitos registros encaminhados/s (o gráfico geralmente chega a 100). Ao executar sp_blitzfirst @seconds = 30, sou alertado sobre muitas buscas encaminhadas/s. Uma vez que o alerta é geral (ou seja, não relacionado a nenhum banco de dados), outros 9 alertas da mesma instrução mencionam: "Forwarded Fetches/Sec High: TempDB Object". E de acordo com a contagem de buscas encaminhadas, há dez ou cem vezes mais buscas encaminhadas no TempDB do que fora do TempDB.
Por último, mas não menos importante, o ISV implementou fortemente gatilhos (que relaciono com as buscas encaminhadas do TempDB).
Minhas perguntas:
- Qual é a diferença entre as duas colunas em duas visualizações?
- Ao lidar com banco de dados lento devido a registros encaminhados em um heap, qual devo usar? (Eu sei que a ajuda da MSFT menciona forwarded_record_count em dm_db_index_physical_stats relacionado especificamente a heaps, ainda não deixando isso mais claro para mim).
- Posso identificar o que no TempDB está causando essas buscas encaminhadas?
Eu tenho um problema que se manifesta da seguinte maneira, meu conhecimento do TempDB não cobre isso (ainda):
- Uma consulta analítica, que roda no SSMS por cerca de 200ms, continua rodando no servidor SQL, quando iniciada a partir do aplicativo, por mais de 60 segundos - isso acontece apenas ocasionalmente, na maioria das vezes o problema não está presente
- A fila de consultas executáveis/suspensas pode crescer até dezenas de consultas do mesmo texto de consulta, sendo uma delas consultas SELECT um bloqueador de cabeça bloqueando outros SELECTs idênticos
- as esperas mais dominantes são SOS_SCHEDULER_YIELD e PAGELATCH_UP para as consultas específicas do mesmo texto e valores de parâmetro, quando as filas executáveis/suspensas começam a crescer significativamente em comparação com a linha de base
- quando o problema ocorre, as dezenas de consultas na fila têm os mesmos valores literais de parâmetros (timestamp de início de turno, id de funcionário e área de produção)
- as queries que estão sendo suspensas (durante o tempo do snapshot do nosso monitoramento - DBA Dash) têm a espera PAGELATCH_UP como a mais dominante e estão esperando a página GAM em tempdb
- a consulta não está vazando para o tempdb quando verifico o plano de execução no SSMS, usando os parâmetros da consulta que continua se acumulando nas filas executáveis/suspensas
Configuração do servidor, do banco de dados e do tráfego do banco de dados:
- 4 a 6 núcleos (o problema ocorreu independentemente em dois servidores diferentes com contagem de núcleo diferente)
- 4 - 6 arquivos TempDB de tamanho uniforme
- 40 GB de RAM atribuídos à instância
- no banco de dados específico, o RCSI + Snapshot está ativado (portanto, o TempDB está sendo atingido)
- nenhuma exclusão está ocorrendo nas duas tabelas nas quais a consulta é executada, apenas INSERTs e SELECTs - apenas 1 linha por vez é inserida
- SELECTs estão atingindo geralmente os registros mais novos (aqueles inseridos recentemente)
- o servidor está fazendo geralmente 400 - 700 solicitações em lote/s; Quando ocorre o problema, atinge um pico de até 1500, criando alta carga de E/S + CPU em comparação com a operação normal
- os dados na tabela têm distribuição mais ou menos uniforme, ou seja, nenhum funcionário em nenhum turno para determinada área de produção tem significativamente mais registros do que os outros
- a captura de tela em anexo é uma tabela que mostra o instantâneo do DBA Dash em um momento em que o problema se manifesta totalmente
- tempDB, apesar do snapshot RCSI+ não crescer muito, são alguns GBs em um drive de 60GB (status estável por vários meses e depois de alguns episódios do que descrevo aqui)
- todas as consultas SELECT na captura de tela têm espera PAGELATCH_UP, aproximadamente metade delas tem as seguintes informações adicionais:
- tipo de recurso de espera: PAGE
- recurso de espera: 2:3:2 (acho que o significado é: banco de dados tempdb, 3º arquivo em tempdb, 2ª página que estamos esperando)
- arquivo de espera: PRIMÁRIO | temp2
- tipo de página: GAM
- Esperar para compilar: Falso
Além do esforço óbvio para chegar à causa raiz e corrigi-la permanentemente, minhas principais perguntas seriam:
- como é que as consultas SELECT podem acessar páginas GAM pesadamente em tempdb?
- se eu admitir que SELECT pode tocar na página GAM com frequência, o que pode impedir o progresso da consulta (bloqueador de cabeça) (ou seja, ler a página GAM e disponibilizá-la imediatamente para outras pessoas)?
Apontar para qualquer recurso / conselho de estudo relevante seria muito apreciado
EDIT: Para responder ao comentário de John, gostaria de acrescentar o seguinte:
- CTFP: 30
- MAXDOP: 4 (definido para ambos os servidores SQL, embora um tenha 6 núcleos, o outro tenha 4)
- existem 2 instâncias por SQL VM - esta instância em que ocorreu o problema, depois outra instância de "escritório", que coloca uma carga insignificante na VM do servidor SQL
- Tabelas
ManualPanelEntries : 6933089 registros, 1221 MB de dados, 2591 MB de índices - de fato, os índices consomem mais espaço do que os próprios dados
Pesos : 3108486 registros, 178 MB de dados, 170 MB de índices
- Todo o banco de dados: 125 GB
============
O que descobri depois de escrever a postagem é que também o bloqueador de cabeça (um dos muitos SELECTs paralelos idênticos) espera pelo GAM, segunda página de um arquivo tempdb específico. Como se algo mais (armazenamento de versão?) Bloqueasse uma página GAM específica, impedindo que outras consultas usando o TempDB continuassem.
Estou usando o SQL Server SE 2019, em um Windows Server 2019 (com unidade SSD) que executa o IIS 10. Sobre o IIS 10, execute um aplicativo ASP.Net, que deve ser considerado COMO ESTÁ (não posso modificá-lo) .
Ultimamente descobri que o aplicativo ASP.Net pode se tornar um pouco tagarela demais e começar a fazer muitas consultas de banco de dados em lotes (poucas rajadas de 20 a 30 consultas/s). Sob carga pesada, isso pode se tornar um problema, então gostaria de melhorar o desempenho do sistema. O SQL Server foi instalado sem nenhuma configuração específica (padrão do assistente de instalação).
Gostaria de saber se existe alguma configuração conhecida que eu possa ajustar (SQL Server/IIS) que possa otimizar o cenário em que há muitas consultas pequenas e rápidas (~5ms por consulta) enviadas em lotes de 20-30 consultas/s . Para que eu possa melhorar a situação em que o aplicativo ASP.Net está sob carga pesada e começar a enviar muitas consultas rápidas ao banco de dados
Ok, então eu tenho uma série de VMs da AWS, principalmente usando a classe de servidor z1d.3xlarge com SQL Server 2019 integrado, cada um desses servidores contém um NVMe de vários tamanhos. (Não surpreendentemente) Coloquei minha unidade SQL Server TempDB nesta unidade, funciona muito bem, sem problemas.
Agora estou tentando fazer exatamente a mesma coisa no Azure, neste caso estou usando a classe "Standard E4bds v5" com uma licença SQL Server 2022 dev, mesmo acordo, NVMe anexado, alto desempenho (verificado por "atto" comparando-o, ele realmente funciona melhor), DEVE funcionar bem, exceto que não...
Por exemplo, tenho uma consulta que gera um grande vazamento de TempDB quando executada em qualquer um dos servidores (gera o mesmo plano de consulta em ambos):
Azure
AWS (mesmo plano exato)
Mesma consulta, mesmo plano, mesmo derramamento de tempDB, no servidor AWS, 3 minutos, no servidor Azure 11 minutos. Por que? Além de mexer com várias estatísticas de espera e perfmon, ele aparece quando o derramamento de TempDB ocorre no servidor Azure, meio que sites a 25 MB/por segundo:
Onde, se você executar a mesma coisa no servidor AWS, verá picos de até 900 MB/por segundo. Olhando para isso, acredito que tudo o que está levando à redução do desempenho de E/S da unidade TempDB também está levando a tempos de execução estendidos. Analisei os seguintes fatores:
CPU : geralmente baixo em ambos os servidores, menos de 10% na maioria das vezes
Memória : Esta consulta faz com que o servidor SQL ocupe cerca de 1 GB ou mais, está usando muito pouca memória , são apenas 12% da memória usada no servidor, desativei a paginação e habilitei a memória bloqueada, sem efeito
Outro disco IO : Tudo é um SSD Premium, benchmarks ótimos, parece bom em Perfmon , posso ver no Monitor de recursos que a maior parte do uso é focada na unidade "D" (tempDB):
Activity Monitor : Apenas mostra um monte de leituras quando está em execução, uma pequena quantidade de BufferIO espera:
Qual é a causa mais provável desse baixo desempenho, o que causaria um gargalo na velocidade do TempDB (neste caso, mas não em outras consultas), como eu determinaria a diferença entre os dois servidores que está contribuindo para a diferença de velocidade da consulta?
Atualização 1
Por solicitação de JD, postei abaixo o benchmark do CrystalMark das unidades TempDB em cada servidor
Desempenho da unidade temporária da AWS:
Desempenho da unidade temporária do Azure:
Por algum motivo, este benchmark mostra um desempenho pior nas unidades do Azure em comparação com as da AWS (este é um resultado diferente do benchmark ATTO, que mostrou o oposto). Talvez seja isso que está acontecendo, tenho me concentrado na " série Ebsv5 " até agora, vou tentar obter um servidor muito maior que, em teoria, deveria me conceder mais "IOPS/MBps" em todas as unidades (não certeza se isso afeta o NVMe's...).
Também vou fazer benchmark de um servidor maior e ver se ele tem melhor desempenho, postarei os resultados aqui.
Atualização 2
Sim, JD está certo, "Standard_E16-8ads_v5" é muito melhor, dê uma olhada:
Estou tentando resolver algum mistério em dois dos meus ambientes. Ambas são implantações do SQL 2019, porém uma possui o Kerberos configurado (ou seja, os SPNs são registrados para a instância e a porta), enquanto a outra não. Eu tenho tentado investigar como isso aconteceu, mas ainda não cheguei ao fundo disso.
Basicamente, gostaria de entender o requisito para implantações futuras. Devo criar manualmente (ou solicitar a criação) dos SPNs ou há alguma maneira de criá-los automaticamente? Por exemplo, eles poderiam ter sido criados durante a construção da camada do aplicativo?
Eu apreciaria se alguém é capaz de lançar alguma luz sobre isso para mim, por favor. É claro que tenho pesquisado tudo sobre autenticação Kerberos e SPNs, mas se houver algum artigo específico sobre essa questão específica, gostaria de um link para ele, por favor.
Obrigado
Desejo selecionar todos os cliques e visualizações para determinados objetos. Cliques e visualizações são rastreados em tabelas separadas, mas quero 1 linha retornada para um objeto com as visualizações e cliques combinados. Isso funciona corretamente com o seguinte SQL:
SELECT * FROM (
SELECT distinct(title)
,ROW_NUMBER() OVER (ORDER BY id ASC) AS RowNum
,SUM(vws) as vws,SUM(clicks) as clicks,id FROM(
SELECT l.id,l.title,0 as vws, COUNT(lc.id) as clicks
FROM locs l
INNER JOIN locs_clicks lc on l.id=lc.locid
GROUP BY l.title,l.id
UNION
SELECT l.id,l.title,COUNT(lv.id) as vws,0 as clicks
FROM locs l
INNER JOIN locs_views lv on l.id=lv.locid
GROUP BY l.title,l.id
)t
GROUP BY title,id
) as info
WHERE RowNum > 0 AND RowNum <= 100
Eu recebo um resultado como:
title RowNum vws clicks id
Mercedes Benz 12697 43 2 17231289
No entanto, quando quero classificar em visualizações ( vws
) e alterar 1 linha:
`,ROW_NUMBER() OVER (ORDER BY vws ASC) AS RowNum`
Eu recebo o erro:
A coluna 't.vws' é inválida na lista de seleção porque não está contida em uma função agregada ou na cláusula GROUP BY.
Mas então, quando eu mudo para GROUP BY title,id,vws
terminar com esta consulta:
SELECT * FROM (
SELECT distinct(title)
,ROW_NUMBER() OVER (ORDER BY vws ASC) AS RowNum
,sum(vws) as vws,sum(clicks) as clicks,id FROM(
SELECT l.id,l.title,0 as vws, COUNT(lc.id) as clicks
FROM locs l
INNER JOIN locs_clicks lc on l.id=lc.objectid
GROUP BY l.title,l.id
UNION
SELECT l.id,l.title,COUNT(lv.id) as vws,0 as clicks
FROM locs l
INNER JOIN locs_views lv on l.id=lv.objectid
GROUP BY l.title,l.id
)t
GROUP BY title,id,vws
) as info
WHERE RowNum > 0 AND RowNum <= 100
As linhas não são mais agrupadas em 1 linha por título distinto:
title RowNum vws clicks id
Mercedes Benz 699 0 2 17231289
Mercedes Benz 18102 43 0 17231289
Como posso selecionar linhas únicas e title
ter clicks
e vws
ainda no mesmo resultado/linha retornado?
No final da tarde de ontem, adicionei 4 arquivos de dados tempdb aos 4 existentes, totalizando 8 (16 processadores no servidor SQL). Eu também os pré-aumentei para quase 100% do espaço disponível.
Hoje fui contatado por um de nossos desenvolvedores informando que ontem ela estava executando uma consulta que retornaria um conjunto inicial de resultados para a exibição do ssms em 3 a 5 segundos e toda a consulta seria concluída em 2 a 3 minutos. Hoje, a consulta leva 5 minutos para ser concluída e nenhum resultado é exibido em ssms por cerca de 2,5 minutos.
Não havia outras consultas em execução no momento. O uso da CPU foi baixo. Eu devolvi o servidor e não houve melhora. Agora, estou me perguntando se minha alteração no tempdb causou a diminuição no desempenho. Não consigo ver como, mas a paranóia está se instalando. Executei a consulta e monitorei o tempdb durante a execução e não parecia usar o tempdb, o que acho estranho, pois tem uma instrução GROUP BY que acredito usar tempdb. A tabela contém cerca de 22 milhões de linhas e a consulta retorna cerca de 7,8 milhões.
select
DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0) as Quarter
,[PartnerCD]
,[PartnerNM]
,[PartnerGRP]
,[BizMemberID]
,[MemberID]
,[BizType]
,[RateCD]
,[Rate]
,sum([MemberMonth]) as MemberQuarter
,[CurrentAge]
,[AgeAtTime] = CASE WHEN dbo.fn_CalculateAge(BirthDT, (DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)), 'YEAR') < 0 THEN NULL ELSE dbo.fn_CalculateAge(BirthDT, (DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)), 'YEAR') END
,AgeCategory = dbo.fn_CalculateAgeCatYrsOrdered(BirthDT, (DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)))
,[BirthDT]
,[ZipCD]
FROM [Partner].[dbo].[Membership]
group by DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)
,[PartnerCD]
,[PartnerNM]
,[PartnerGRP]
,[BizMemberID]
,[MemberID]
,[BizType]
,[RateCD]
,[Rate]
,[CurrentAge]
,[BirthDT]
,[ZipCD]
É provável que minha alteração tenha causado a diminuição do desempenho ou provavelmente é coincidência?
Estou construindo um quadro de tarefas simples (usando MS SQL/ASP.NET core/C#) e tenho uma dúvida sobre o design do banco de dados. Não sei decidir se devo criar uma tabela separada ou não em determinadas situações.
Tenho as seguintes tabelas:
- Trabalho
- Categoria
- Indústria
- Região
Na tabela Job, armazeno o salário no campo 'Salary', mas também preciso armazenar o 'SalaryPeriod', ou seja, com que frequência o salário é pago: por ano, mês, semana, dia ou hora.
É melhor 1) criar uma tabela SalaryPeriod que contém as 5 opções (anual, mensal, etc.) ou é melhor 2) armazenar o período salarial como uma string na tabela Job?
Estou inclinado para o número 1 porque:
- É mais fácil manter os dados, por exemplo, se eu precisar editar ou adicionar aos tipos de salário (acho que não vou modificar as opções para ser honesto, mas nunca se sabe)
- Eu não tenho problemas de desempenho