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 / dba / Perguntas / 319327
Accepted
SEarle1986
SEarle1986
Asked: 2022-11-08 15:46:06 +0800 CST2022-11-08 15:46:06 +0800 CST 2022-11-08 15:46:06 +0800 CST

É possível que o SQL Server conceda mais memória a uma consulta do que a disponível para a instância

  • 772

Outro dia me perguntaram o que aconteceria se o SQL Server quisesse executar uma única consulta que recebesse mais memória do que a disponível para a instância. Meus pensamentos iniciais eram de que eu poderia ver RESOURCE_SEMAPHOREesperas e a consulta nunca seria iniciada.

Fiz alguns testes para tentar descobrir.

Minha instância inicia em 4000 MB de RAM:

EXEC sys.sp_configure N'max server memory (MB)', N'4000'
GO
RECONFIGURE WITH OVERRIDE
GO

Se eu executar minha consulta (deliberadamente horrível):

USE StackOverflow
SELECT      CONVERT(NVARCHAR(4000), u.DisplayName) AS DisplayName,
            CONVERT(NVARCHAR(MAX), u.DisplayName) AS Disp2,
            CONVERT(NVARCHAR(MAX), u.DisplayName) AS Disp3
FROM        dbo.Users AS u
            JOIN dbo.Posts p
                ON LTRIM(u.DisplayName) = LTRIM(p.Tags)
WHERE       u.CreationDate >= '2008-12-25'
            AND u.CreationDate < '2010-12-26'
ORDER BY    u.CreationDate;

O plano de execução diz que a memória concedida é de 732.008 KB.

Em seguida, defino a memória disponível para minha instância abaixo desse número e reinicio a instância:

EXEC sys.sp_configure N'max server memory (MB)', N'500' /* a value lower than the previous memory grant */
GO
RECONFIGURE WITH OVERRIDE
GO

Executei a consulta novamente e descobri que ela recebe menos memória do que antes (93.176 KB), mas o plano é, na verdade, uma forma diferente.

Em seguida, executei a consulta novamente e usei uma dica de consulta para forçar o plano original a ver qual memória é concedida:

USE StackOverflow
SELECT      CONVERT(NVARCHAR(4000), u.DisplayName) AS DisplayName,
            CONVERT(NVARCHAR(MAX), u.DisplayName) AS Disp2,
            CONVERT(NVARCHAR(MAX), u.DisplayName) AS Disp3
FROM        dbo.Users AS u
            JOIN dbo.Posts p
                ON LTRIM(u.DisplayName) = LTRIM(p.Tags)
WHERE       u.CreationDate >= '2008-12-25'
            AND u.CreationDate < '2010-12-26'
ORDER BY    u.CreationDate
OPTION (RECOMPILE, USE PLAN N'<xml here>'

Descobri que a consulta agora usa o plano original, mas obtém uma concessão de memória muito semelhante ao plano compilado (93.168 KB) - plano real forçado

Isso parece refutar minha teoria de que eu veria RESOURCE_SEMAPHOREesperas e sugere que há algum mecanismo que impede o SQL Server de conceder mais memória do que está disponível para uma consulta (o que parece perfeitamente sensato!) Aliás, se eu executar a consulta duas vezes em sessões simultâneas no Configuração de servidor de 500 MB, ambas as sessões RESOURCE_SEMAPHOREaguardam o que parece indefinidamente.

Eu posso ver MaxQueryMemoryno plano que parece ser o que está impedindo o SQL Server de conceder mais memória do que tem disponível para uma consulta.

É possível que uma única consulta receba mais memória do que a disponível para a instância? Se não, MaxQueryMemoryo que faz com que o SQL Server não atribua mais memória do que a disponível e como esse número é calculado?

NB - Meu banco de dados StackOverflow está no nível de compatibilidade 130

sql-server
  • 1 1 respostas
  • 1199 Views

1 respostas

  • Voted
  1. Best Answer
    Erik Darling
    2022-11-08T16:33:46+08:002022-11-08T16:33:46+08:00

    Por padrão, o SQL Server permitirá que qualquer consulta use até 25% da memória máxima do servidor para uma concessão de memória, mas, na prática, geralmente está mais perto de 20%.

    O Resource Governor tem algo a dizer sobre isso:

    NOZES

    Mas na minha VM de demonstração com Max Server Memory definido como 90 GB, a maior concessão de memória de consulta única que posso obter é 17 GB, não 22 GB.

    WITH
        c AS 
    (
    SELECT
        c.*,
        n = 
            ROW_NUMBER() OVER 
            (
                PARTITION BY 
                    c.PostId 
                ORDER BY 
                    c.Score DESC
            )
    FROM dbo.Comments AS c
    )
    SELECT
        c.*
    FROM c
    WHERE n = 0;
    

    Aqui está o plano parcial para isso:

    NOZES

    Usando sp_PressureDetector , você pode obter várias informações sobre o uso de memória para um SQL Server. Para mantê-lo em concessões de memória, é isso que acontece quando executo a consulta acima:

    NOZES

    Não é até que eu execute quatro cópias da consulta que se espera em uma fila no semáforo de recurso:

    NOZES

    Aguarde informações:

    NOZES

    Uma maneira geral de pensar sobre isso é que o SQL Server fornecerá cerca de 75% da memória máxima do servidor para consultas que solicitam concessões.

    Nesse caso, 68 GB de memória estão disponíveis para concessões de 90 GB. Como a quarta consulta teria ultrapassado essa marca de ~ 75%, ela teria que esperar.

    Em geral, a bolsa total mais 50% tem que estar disponível para que a memória seja concedida imediatamente. Caso contrário, ele aguardará, às vezes até que uma concessão mais baixa seja forçada (reveja a forced_grant_countcoluna em sys.dm_exec_query_resource_semaphores)

    Você pode aprender mais detalhadamente sobre como o SQL Server prioriza filas de semáforos e concessões de memória em geral a partir destas fontes:

    • Consultar concessões de memória e semáforos de recursos no SQL Server
    • Habilitando o Resource Governor para corrigir concessões de memória
    • Domínio do ajuste de consultas: Zen e a arte da memória do espaço de trabalho

    Lembre-se de que minha resposta é apenas em referência ao modo de linha tradicional e às cargas de trabalho de armazenamento de linha. Adicionar em modo de lote e índices de armazenamento de coluna mudará alguns comportamentos, particularmente em relação ao respeito pela memória máxima do servidor e o que requer uma concessão de memória.

    Com o modo de linha, os locais mais comuns em que você verá concessões de memória concedidas a consultas são quando os planos de consulta apresentam:

    • Classificações
    • Junções ou agregações de hash
    • Loops aninhados otimizados

    As inserções em índices de armazenamento de colunas solicitarão memória mesmo quando não houver nenhuma classificação de solicitação DML no plano de consulta para realizar a compactação.

    • 16

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

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