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 / 13647
Accepted
RK Kuppala
RK Kuppala
Asked: 2012-02-23 06:06:12 +0800 CST2012-02-23 06:06:12 +0800 CST 2012-02-23 06:06:12 +0800 CST

Ajuste de consulta - SQL Server

  • 772

Um de nossos desenvolvedores está tentando executar a consulta abaixo em um servidor de desenvolvimento, que envolve extrair dados de um servidor vinculado, produção. A consulta foi executada por mais de 14 horas antes de ser interrompida.

Observei o plano de execução no SQL Sentry Plan Explorer - encontre o plano de execução abaixo.

Como essa consulta pode ser ajustada para melhor desempenho? Há algum erro flagrante na consulta? Existem dicas, postagens de blogs que me ajudarão a melhorar essa consulta?

Ambos os servidores envolvidos são SQL Server 2005

SELECT A.SETID
,A.CUST_ID
,A.CNTCT_SEQ_NUM
,A.NAME1
,A.TITLE
,C.DESCR
FROM PS_CUST_CONTACT A
,[linksrv].[prodDB].dbo.PS_BO_ROLE Z
,[linksrv].[prodDB].dbo.PS_RD_PERSON B
,[linksrv].[prodDB].dbo.PS_BO_ROLE_TYPE C
WHERE Z.BO_ID = B.BO_ID
AND Z.ROLE_TYPE_ID = C.ROLE_TYPE_ID
AND Z.ROLE_END_DT >= GETDATE()
AND A.EFFDT = (
    SELECT MAX(EFFDT)
    FROM PS_CUST_CONTACT CUST_CONTACT
    WHERE CUST_CONTACT.SETID = A.SETID
        AND CUST_CONTACT.CUST_ID = A.CUST_ID
        AND CUST_CONTACT.CNTCT_SEQ_NUM = A.CNTCT_SEQ_NUM
        AND CUST_CONTACT.EFFDT <= { FN CURDATE() }
    )
AND A.EFF_STATUS = 'A'
AND B.PERSON_ID IN (
    SELECT A1.PERSON_ID
    FROM PS_CONTACT A1
        ,PS_CONTACT_CUST B1
    WHERE A1.EFFDT = (
            SELECT MAX(A_ED.EFFDT)
            FROM PS_CONTACT A_ED
            WHERE A1.SETID = A_ED.SETID
                AND A1.CONTACT_ID = A_ED.CONTACT_ID
                AND A_ED.EFFDT <= SUBSTRING(CONVERT(CHAR, GETDATE(), 121), 1, 10)
            )
        AND A1.SETID = B1.SETID
        AND A1.CONTACT_ID = B1.CONTACT_ID
        AND B1.EFFDT = (
            SELECT MAX(B_ED.EFFDT)
            FROM PS_CONTACT_CUST B_ED
            WHERE B1.SETID = B_ED.SETID
                AND B1.CONTACT_ID = B_ED.CONTACT_ID
                AND B_ED.EFFDT <= A.EFFDT
            )
        AND A.CNTCT_SEQ_NUM = B1.CNTCT_SEQ_NUM
        AND A.SETID = B1.CUSTOMER_SETID
        AND A.CUST_ID = B1.CUST_ID
    )

insira a descrição da imagem aqui

sql-server sql-server-2005
  • 1 1 respostas
  • 326 Views

1 respostas

  • Voted
  1. Best Answer
    Darin Strait
    2012-02-23T08:57:12+08:002012-02-23T08:57:12+08:00

    Para aprofundar o que Aaron afirma um pouco mais, o desempenho do servidor vinculado, especialmente para grandes conjuntos de resultados, para junções entre servidores e subconsultas entre servidores, geralmente é decepcionante. Se você observar o servidor remoto com o Profiler, poderá descobrir que o servidor local bombardeia o servidor remoto com solicitações de busca de uma única linha para corresponder às colunas de junção. Quando isso acontece, a latência da rede e a sobrecarga de chamadas conspiram para prejudicar o desempenho.

    Se você puder consultar dados locais sem muitos problemas, seria melhor. Você pode restaurar um backup de produção ou usar SSIS (ou mesmo bcp, ainda funciona) para copiar dados do servidor de produção para algumas tabelas de trabalho no servidor local. Geralmente SSIS, bcp e táticas semelhantes são mais rápidas do que servidores vinculados e podem ajudar a evitar problemas com o crescimento do arquivo de log.

    Se você precisar consultar os dados de um servidor remoto, poderá descobrir que reescrever a consulta para que ela use OPENQUERY() (em vez de nomes de quatro partes) e 'envie' todas as 'partes remotas' da consulta para o servidor remoto e, em seguida, junta os resultados disso aos dados locais será mais eficaz. O SQL deve ser inteligente o suficiente para mover todas as junções para o servidor remoto, mas às vezes isso não acontece e OPENQUERY () fornece um método para forçar o SQL a fazer o que você deseja.

    Outra tática semelhante seria executar primeiro a 'parte remota' da consulta e colocar os resultados em uma tabela temporária, (opcionalmente) indexar a tabela temporária e depois juntar a 'parte local' da consulta à tabela temporária. Novamente, isso ajuda você a forçar o SQL a fazer o que deveria.

    Parece mais trabalhoso, mas o SQL pode se comportar de maneira mais eficiente. Como sempre, observe seus tipos de dados nas junções e seus SARGs ou seus índices serão ignorados.

    • 2

relate perguntas

  • 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

  • Downgrade do SQL Server 2008 para 2005

Sidebar

Stats

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

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 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

    Como selecionar a primeira linha de cada grupo?

    • 6 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
    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
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +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