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 / 137907
Accepted
Paul White
Paul White
Asked: 2016-05-09 06:07:58 +0800 CST2016-05-09 06:07:58 +0800 CST 2016-05-09 06:07:58 +0800 CST

Leituras lógicas diferentes ao acessar os mesmos dados LOB

  • 772

Aqui estão três testes simples que leem os mesmos dados, mas relatam leituras lógicas muito diferentes:

Configurar

O script a seguir cria uma tabela de teste com 100 linhas idênticas, cada uma contendo uma coluna xml com dados suficientes para garantir que ela seja armazenada fora da linha. No meu banco de dados de teste, o comprimento do xml gerado é de 20.204 bytes para cada linha.

-- Conditional drop
IF OBJECT_ID(N'dbo.XMLTest', N'U') IS NOT NULL
    DROP TABLE dbo.XMLTest;
GO
-- Create test table
CREATE TABLE dbo.XMLTest
(
    ID integer IDENTITY PRIMARY KEY,
    X xml NULL
);
GO
-- Add 100 wide xml rows
DECLARE @X xml;

SET @X =
(
    SELECT TOP (100) *
    FROM  sys.columns AS C
    FOR XML 
        PATH ('row'),
        ROOT ('root'),
        TYPE
);

INSERT dbo.XMLTest
    (X)
SELECT TOP (100)
    @X
FROM  sys.columns AS C;

-- Flush dirty buffers
CHECKPOINT;

testes

Os três testes a seguir leem a coluna xml com:

  1. SELECTUma declaração simples
  2. Atribuindo o xml a uma variável
  3. Usando SELECT INTOpara criar uma tabela temporária
-- No row count messages or graphical plan
-- Show I/O statistics
SET NOCOUNT ON;
SET STATISTICS XML OFF;
SET STATISTICS IO ON;
GO
PRINT CHAR(10) + '=== Plain SELECT ===='

DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;

SELECT XT.X 
FROM dbo.XMLTest AS XT;
GO
PRINT CHAR(10) + '=== Assign to a variable ===='

DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;

DECLARE @X xml;

SELECT
    @X = XT.X
FROM dbo.XMLTest AS XT;
GO
PRINT CHAR(10) + '=== SELECT INTO ===='

IF OBJECT_ID(N'tempdb..#T', N'U') IS NOT NULL
    DROP TABLE #T;

DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;

SELECT 
    XT.X
INTO #T
FROM dbo.XMLTest AS XT
GO
SET STATISTICS IO OFF;

Resultados

A saída é:

=== SELEÇÃO Simples ====
Tabela 'XMLTest'. Contagem de varredura 1, leituras lógicas 3, leituras físicas 1, leituras antecipadas 0,
    lob lógico lê 795, lob físico lê 37, lob read-ahead lê 796.

=== Atribuir a uma variável ====
Tabela 'XMLTest'. Contagem de varredura 1, leituras lógicas 3, leituras físicas 1, leituras antecipadas 0,
    lob leituras lógicas 0, lob leituras físicas 0, leitura antecipada de lob 0.

=== SELECIONE EM ====
Tabela 'XMLTest'. Contagem de varredura 1, leituras lógicas 3, leituras físicas 1, leituras antecipadas 0,
    lob lógico lê 300, lob físico lê 37, lob read-ahead lê 400.

Perguntas

  • Por que as leituras de LOB são tão diferentes?
  • Certamente os mesmos dados exatos foram lidos em cada teste?
sql-server performance
  • 1 1 respostas
  • 1367 Views

1 respostas

  • Voted
  1. Best Answer
    Paul White
    2016-05-09T06:07:58+08:002016-05-09T06:07:58+08:00

    Nem todas as leituras são iguais. O SQL Server sabe que o acesso a dados LOB é caro e tenta evitá-lo sempre que possível. Também existem diferenças detalhadas na forma como os dados LOB são lidos em cada caso:

    Resumo

    Os números são diferentes porque:

    • O select lê o LOB em pedaços do tamanho de um pacote
    • O teste de atribuição de variável não lê o LOB de forma alguma
    • O teste "selecionar em" lê o LOB em páginas inteiras

    Detalhe

    1. AviãoSELECT

      Selecione o plano

      O Clustered Index Scan não lê nenhum dado LOB. Ele apenas atribui um identificador de LOB do mecanismo de armazenamento . O identificador não é usado até que o controle retorne à raiz do plano.

      O conteúdo LOB da linha atual é lido em blocos do tamanho do pacote TDS e transmitido para o cliente. As leituras lógicas contam o número de vezes que uma página é tocada, então:

      O número de leituras relatadas é igual ao número de leituras em partes executadas, mais uma para cada vez que ocorre uma transição de página LOB.

      Por exemplo: Uma leitura lógica é contada no início de cada bloco conforme o processo toca a página correspondente à posição atual do fluxo. Onde os pacotes são menores que uma página de banco de dados (o caso usual), várias leituras lógicas são contadas para a mesma página. Se o tamanho do pacote fosse tão grande que todo o LOB pudesse caber em um bloco, o número de leituras lógicas relatadas seria o número de páginas do LOB.

    2. Atribuição variável

      plano variável

      O Clustered Index Scan atribui um identificador LOB como antes. Na raiz do plano, o identificador LOB é copiado para a variável. Os próprios dados LOB nunca são acessados ​​(zero leituras de LOB), porque a variável nunca é lida. Mesmo que fosse, seria apenas por meio do identificador LOB atribuído pela última vez.

      Não há leituras LOB porque os dados LOB nunca são acessados.

    3. SELECT INTO

      Selecione no plano

      Este plano usa o provedor de conjunto de linhas em massa para copiar os dados LOB da tabela de origem para a nova tabela. Ele processa uma página LOB completa em cada leitura (sem streaming ou fragmentação).

      O número de leituras lógicas corresponde ao número de páginas LOB na tabela de teste.

    • 27

relate perguntas

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

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

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

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