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-92411

Kirk Saunders's questions

Martin Hope
Kirk Saunders
Asked: 2022-03-22 13:39:17 +0800 CST

Arquitetura de replicação transacional - um artigo - vários assinantes

  • 1

P: É mais barato/mais eficiente para um Distributorservidor usar 1 publicationpara 2 subscribersou usar 2 publicationscom o mesmo articlesindo para um único subscribercada?

Detalhes:

Temos tido um problema recentemente com nossos Transactional Replicationprocessos Distributorpara Subscriberinterromper e não recuperar normalmente. É quase como se algumas transações fossem ignoradas ou aplicadas fora de ordem. Historicamente, acabamos de resolver isso com reinitializingo publicatione seguindo em frente.

Reduzimos isso a um problema de utilização de recursos no Distributorservidor. Na maioria das vezes, podemos resolver reiniciando o servidor, Azuremas os maiores publicationsnem sempre recuperam por conta própria.

Todas as nossas articlesnecessidades devem ser entregues a dois servidores diferentes (um para funções de relatórios pertencentes ao departamento de TI e outro para funções de relatórios pertencentes a uma equipe de analistas de dados). Vamos dividir os vários artigos em grupos, cada grupo recebendo 2 publicationse enviá-los para o nosso Distributorservidor separado que aceita ambos Publications. Um publicationvai para o servidor de TI, o outro vai para o servidor Data Analyst. Algo como abaixo:Arquitetura de replicação atual

O problema de utilização de recursos em parte se deve a consultas caras no servidor Data Analyst blockinga aplicação dos replicationcomandos. Estamos trabalhando com essa equipe para melhorar as consultas, mas também quero ver se podemos fazer um ajuste de arquitetura para ajudar.

Estou olhando para ver se há alguma razão pela qual seria menos caro Distributorenviar 1 publicationpara 2 subscribersem vez de usar 2 publicationsindo para um único subscribercada. Algo como abaixo:Arquitetura de replicação potencial

Alguém tem alguma experiência com este tipo potencial de implementação?

sql-server transactional-replication
  • 1 respostas
  • 46 Views
Martin Hope
Kirk Saunders
Asked: 2020-12-08 10:21:10 +0800 CST

Cláusula WHERE Compare VarChar(n) Coluna = VarChar(MAX) Variável Resultados em Comparação de Desigualdades e Baixo Desempenho de Consulta

  • 2

Hoje cedo eu estava trabalhando em um Reporting Stored Procedureque teve um desempenho ruim. Consegui corrigir o problema alterando uma estática variableque continha uma string de dez caracteres ou menos de VARCHAR(MAX)para VARCHAR(10). Estou procurando entender por que isso teria feito a diferença.

Detalhes Adicionais Se Necessário

A consulta original é muito maior do que o que precisa ser analisado, mas eu vi as coisas abaixo acontecendo, ao juntar o fundamental tablea um Key-Value Pair table, estávamos retornando uma tonelada a mais rowsdo que era realmente necessário (em alguns casos, mais de 14 bilhões de linhas para uma saída final de ~60.000 linhas) e tivemos algumas operações extras (particularmente o Lazy Table Spool). A imagem dessa parte do Plano de Consulta está abaixo: Recorte do Plano de Execução Original

Eu podia ver que uma parte estranha do plano de execução era como @ProgramID variableestava sendo tratado. Essa variável é usada como [Column] = @ProgramIDe Columnfaz parte das tabelas Non-Clustered Indexe é um arquivo VarChar(10). Mas ainda estamos fazendo um Inequality Searchem vez de um Equality Search.

Plano de Execução Original Buscar Fragmento de Predicado

Depois de modificar isso parameter/variablede VarChar(Max)para VarChar(10). O execution timetempo caiu de várias horas para cerca de 30 segundos e o plano tinha uma estrutura bem diferente. Olhando para um trecho semelhante do plano de execução, não estávamos retornando tantas linhas, não temos as operações extras e estávamos fazendo um equality searchon [Column] = @ProgramID(novamente Columnfaz parte das tabelas Non-Clustered Indexe é um VarChar(10)). Novo trecho do plano de execução

Novo Plano de Execução Buscar Fragmento de Predicado

Abaixo está uma consulta simplificada que mostra um pouco desse comportamento (não temos todas as etapas extras, mas a diferença Seek Predicate ainda está lá): ( Paste The Plan )

DECLARE @CompanyID VarChar(10) = 'RxCRoads'
        ,@ClientID VarCHar(10) = 'Amgen'
        ,@ProgramID VarChar(MAX) = 'Foundation'
        ,@StartDate DATETIME = '2020-01-01'
        ,@EndDate DATETIME = '2020-12-07'
        ,@RxOnly INT = 9

SELECT PC.CompanyID,
PC.ClientID,
PC.ProgramID,
PC.PatientID,
PC.CaseID,
RxOnly.[Value] AS RxOnly
FROM PATIENTCASES PC
    LEFT OUTER JOIN PatientCaseDetail RxOnly
        ON RxOnly.CompanyId = PC.CompanyID
        AND RxOnly.ClientId = PC.ClientID
        AND RxOnly.ProgramId = PC.ProgramID
        AND RxOnly.PatientID = PC.PatientID
        AND RxOnly.CaseID = PC.CaseID
        AND RxOnly.PatientCaseAdditionalElementId = @RxOnly
WHERE PC.CompanyID = @CompanyID
AND PC.ClientID = @ClientID
AND PC.ProgramID = @ProgramID
AND PC.CaseCreateDateTime >= @StartDate
AND PC.CaseCreateDateTime < @EndDate

Apenas alterar o @ProgramID VarChar(MAX) = 'Foundation')para @ProgramID VarChar(10) = 'Foundation'retorna um plano mais ágil e melhor desempenho (mesmo que não seja realmente perceptível nesta consulta específica). ( Colar o plano )

Existe algum motivo específico pelo qual essa mudança no tamanho do tipo de dados resultaria na mudança no plano de execução? Executar a mesma consulta com @ProgarmId VarChar(8000)em vez de @Program VarChar(10)não tem diferença perceptível de @Program VarChar(10). ( Colar o plano )

Meu palpite é que VarChar(MAX)tem regras de comparação diferentes devido ao seu tamanho, e isso é apenas um estado do que VarChar(MAX)é. Mas eu não sabia se alguém tinha uma resposta melhor/mais técnica do que eu para que eu possa aplicar melhor essa lição no futuro.

sql-server query-performance
  • 2 respostas
  • 529 Views
Martin Hope
Kirk Saunders
Asked: 2020-05-23 12:22:25 +0800 CST

Armazenar VarChar(Max) [Notas] Coluna na Mesma ou Tabela Separada

  • 4

Isenção de responsabilidade

Eu tive uma ideia para um design de mesa há pouco tempo que fez sentido para mim na época. Na história recente, percebi que tenho o hábito de "engenharia em excesso" ou gastar muito tempo tentando "otimizar demais" as soluções. Estou assumindo que este é um daqueles casos em que estou pensando demais na solução e criarei uma sobrecarga extra com pouco ou nenhum ganho real.

Pergunta

Suponha que para um objeto (um Shipment tablepor exemplo) existe algum tipo de NOTE varchar(MAX)elemento de dados que queremos acompanhar. O NOTE columntem a oportunidade de ter dados empurrados para um estouro e aumentar drasticamente o tamanho do row(limitando assim o número rowsque pode ser salvo no page). Pelo que entendi, isso impacta negativamente no tempo de execução de várias operações na tabela como um todo.

Existe algum caso em que devemos empurrar isso columnpara um stand separado sozinho ShipmentNote tableem vez de mantê-lo como columnum Shipment table? A teoria é que, se empurrarmos o NOTE columnpara um separado table, ele salva o pageson the, o Shipment tableque permite que todas as operações no the Shipment tabletenham um desempenho melhor. Porque o rowtamanho é menor e agora você pode caber mais rowsno mesmo page.

(Veja exemplos de esquema abaixo):

Diagrama ER

O principal caso de uso em que isso pode ser uma boa ideia é se:

  • O Note columné regularmente mais de 8000 caracteres (o que eu acho que é quando começamos a usar a paginação extra)
  • O Note columnúnico retornado em SELECToperações e raramente ou nunca é usado como parte de um JOINouWHERE
  • O restante será consultado independentemente de columnsforma regular (IE: a maioria de nossas operações, não utilizará , seja isso ou condições acontecendo em outros em `Remessa)ShipmentNoteNoteJOINWHEREcolumns

As desvantagens que estou vendo (fora disso, podem não fazer melhorias perceptíveis no trabalho com a Shipmenttabela fora da Notecoluna):

  • Agora se torna impossível (ou pelo menos requer um triggerou outra coisa) garantir que sempre haja algum tipo de valor para NOTE(IE: porque agora está em um separado child table, não podemos garantir que NOTEseja NOT NULLpara todos rowemShipment
  • Qualquer operação utilizando NOTEagora exigirá um esforço extra, devido à necessidade de fazer um JOINpara garantir que estamos trabalhando com o registro correto
sql-server database-design
  • 2 respostas
  • 612 Views
Martin Hope
Kirk Saunders
Asked: 2020-05-15 13:55:35 +0800 CST

Integridade Referencial - Chave Estrangeira Indireta em "Profundidade"

  • 3

Pergunta

Qual é a melhor prática para garantir que uma chave de uma tabela "Grand-Parent" ou "Bis Grand-Parent" seja mantida quando uma tabela "Child" ou "Grand-Child" é criada a partir de várias árvores de relacionamento.

Detalhes, já que essa pergunta provavelmente não faz sentido

Estou tentando construir um banco de dados para acompanhar o status de execução dos processos automatizados em execução em nosso ambiente.

Em geral temos um "Job" que aciona um ou mais "Executáveis" e esses "Executáveis" podem executar tarefas para um ou mais clientes. Teremos então 2 tabelas de registro, uma que rastreia quando um "Job" foi iniciado e outra que registrará o status de Sucesso x Falha de cada instância "ExecutableCustomer".

Um Esquema Simplificado Planejado está abaixo: Diagrama ER

Quando corrigirmos o registro para o JobExecutableCustomerExecutionLog, gostaria de garantir que o Job.IDvalor associado ao JobExecutionLog.IDvalor corresponda ao Job.IDvalor associado ao JobExecutableCustomer.ID.

Normalmente eu lidaria com isso com um Foreign Keymas uma vez que Job.IDnão é armazenado em JobExecutableCustomer, JobExecutableCustomerExecutionLognem JobExecutionLog. A relação é indireta.

Exemplo:

Tenho 2 empregos, "Enviar e-mail" e "Enviar mensagem de texto". "Enviar Email" inicia um único executável que pertence a 1 Cliente. "Enviar mensagem de texto" possui 2 executáveis ​​(ambos executados para o mesmo cliente). Quero ter certeza de que, quando o registro for gravado JobExecutableCustomerExecutionLogpara "Enviar e-mail", o Job.IDassociado JobExecutableCustomerExecutionLog.JobExecutableCustomerIDe JobExecutableCustomerExecutionLog.JobExecutionLogID(depois de percorrer os relacionamentos) realmente pertença a Job.ID"Enviar e-mail" e não a "Enviar mensagem de texto".

Pelo que vejo tenho 2 opções:

  1. Empurre o valor de Job.IDtodas as tabelas filhas e torne-o parte doForeign Key
  2. Ter outro processo ( Triggerou Indexed View) garantir os relacionamentos para mim

Eu pessoalmente não gosto da ideia de empurrar o Job.IDvalor em todas as outras tabelas filhas, então estou inclinado a usar a Triggerou outra coisa para lidar com isso. Eu não sabia se essas eram minhas únicas duas opções ou se eu tenho a capacidade de configurar um "normal" Foreign Keypara percorrer os relacionamentos até o fim. Em algum tipo de Cascadeou alguma outra coisa.

sql-server database-design
  • 2 respostas
  • 211 Views
Martin Hope
Kirk Saunders
Asked: 2020-04-02 11:42:14 +0800 CST

Método para encontrar o registro principal com condições WHERE em tabelas filhas

  • 0

Configurar

Recentemente trabalhei em uma otimização para uma Consulta SQL que retornou o Produto de Prescrição usado mais recentemente por um Paciente. A consulta original tratou isso por meio de 3 aninhados CTEe teve um desempenho muito ruim após a migração para um novo servidor. Em vez de tentar fazer a versão original funcionar com ajustes de servidor ou alterações de índice, modificamos a consulta usando ROW_NUMBER()partições. Isso levou o tempo de execução da consulta de cerca de 10 minutos para cerca de 6 segundos para aproximadamente 215.000 linhas na saída final.

Pergunta

Eu estou olhando para ver se há uma maneira melhor do que como eu o reescrevi, já que na minha mente isso quase parece um hack. Eu só quero ver se isso só está funcionando bem por causa do tamanho do nosso conjunto de dados ou se isso realmente é uma boa solução. Eu diria que preferimos usar algum tipo de solução que utiliza alguns JOINs diferentes que encontram esse tipo de informação em vez de usar ROW_NUMBER()e um arquivo CTE.

detalhes adicionais

Por causa desta pergunta, vou deixar de fora alguns detalhes em nosso banco de dados que são menos do que desejáveis ​​(chaves primárias compostas, usando VarChar(1)em vez de um BIT, etc...) para que a raiz da pergunta possa ser melhor abordada.

Temos 4 tabelas no escopo:

  • Patient- vamos apenas retornar a Coluna de Identidade desta tabela
  • OrderHeader- contém informações sobre o pacote, como o endereço para o qual está indo. E é o registro pai para OrderDetail. Esta tabela está vinculada por Patientmeio de uma PatientIDcoluna.
  • OrderDetail- cria uma relação entre OrderHeadere Productpara indicar quais Produtos foram na caixa real quando foi enviado
  • Product- mantém a lista de produtos

Estamos precisando de uma consulta que retorne para cada paciente, o OrderDetailregistro superior, para o OrderHeaderregistro superior, onde o Productregistro vinculado ao OrderDetailregistro Product.IsRx= 1.

Infelizmente, não podemos simplesmente obter o MAXvalor de OrderDetail.IDwhere Product.IsRx= 1, pois isso OrderDetail.IDpode não pertencer ao MAXvalor de OrderHeader.ID. Também não podemos confiar no MAXvalor para OrderHeader.ID, pois não é garantido que tenha um registro, OrderDetailnem nenhum registro lá é garantido que tenha a Product.IsRx= 1

Resolvi esse problema com a consulta abaixo:

WITH CTE
(
    PatientID,
    OrderHeaderID,
    OrderDetaillID,
    ProductNDCCode,
    ProductNDCDescription,
    RowNumber
)
AS
(
    SELECT P.ID AS 'PatientID',
    H.ID AS 'OrderHeaderID',
    D.ID AS 'OrderDetaillID',
    P.NDCCode AS 'ProductNDCCode',
    P.NDCDescription AS 'ProductNDCDescription',
    ROW_NUMBER() 
    OVER
    (
    PARTITION BY P.ID
    ORDER BY 
        P.ID ASC, --This part in the ORDER BY may not be needed, I apologize if it is unnecessary
        SH.OrderHdrID DESC, 
        SD.OrderDtlID DESC
    ) AS 'RowNumber'
    FROM Patient P
        INNER JOIN OrderHeader H
            ON P.ID = H.PatientID
        INNER JOIN OrderDetail D
            ON H.ID = D.OrderHeaderID
        INNER JOIN Product PR
            ON PR.ID = D.ProductID
    WHERE PR.IsRx = 1
)
SELECT PatientID,
OrderHeaderID,
OrderDetaillID,
ProductNDCCode,
ProductNDCDescription
FROM CTE
WHERE RowNumber = 1

Uma orientação ou experiência que eu poderia obter seria muito útil.

sql-server t-sql
  • 1 respostas
  • 34 Views
Martin Hope
Kirk Saunders
Asked: 2019-10-30 07:31:24 +0800 CST

O otimizador de consultas prefere consultar constantes antes de colunas?

  • 3

Acho que já encontrei a resposta para isso, mas espero obter alguma perspectiva adicional.

Suponha que estamos JOINjuntando duas tabelas em uma coluna compartilhada e cada tabela tem uma diferente columnna qual faremos uma Constantpesquisa. Quando construímos um indexpara suportar a consulta, para cada tabela queremos colocar o JOINing columnprimeiro ou o Constant columnprimeiro? Estou pensando agora que é o Constant columnprimeiro. Quando observo um plano de consulta para uma consulta diferente que gerou essa pergunta, parece que ele tenta criar um subconjunto de cada tabela e, em seguida JOIN, juntá-los. Em vez de JOINjuntar as duas tabelas e filtrar a partir daí.

EX: Juntar Remessas a Clientes onde a Remessa é Enviada e o Cliente está Ativo

SELECT [Columns]
FROM Shipment S
   INNER JOIN Customer C
      ON S.CustomerID = C.CustomerID
WHERE S.IsShipped = 1
AND C.IsActive = 1

Estou pensando que os dois melhores índices para usar estão abaixo. Porque Query Optimizerpreferiria escanear o Constantprimeiro e depois JOINo segundo , columnem vez de juntar JOINos dois tablese filtrar o constantdepois.

CREATE NONCLUSTERED INDEX [IX_IsActive-CustomerID] ON [dbo].[Customer]
(
    [IsActive] ASC,
    [CustomerID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

CREATE NONCLUSTERED INDEX [IX_IsShipped-CustomerID] ON [dbo].[Shipment]
(
    [IsShipped] ASC,
    [CustomerID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

Ao invés de:

CREATE NONCLUSTERED INDEX [IX_CustomerID-IsActive] ON [dbo].[Customer]
(
    [CustomerID] ASC,
    [IsActive] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

CREATE NONCLUSTERED INDEX [IX_CustomerID-IsShipped] ON [dbo].[Shipment]
(
    [CustomerID] ASC,
    [IsShipped] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

Isso está certo?

sql-server index
  • 1 respostas
  • 81 Views
Martin Hope
Kirk Saunders
Asked: 2019-07-13 05:19:42 +0800 CST

TSQL Dinâmico Parametrizado - Parâmetros Dinâmicos

  • 1

Temos uma situação em que efetivamente o mesmo relatório é solicitado por clientes diferentes, mas eles:

  1. Não quero todas as colunas
  2. Quer as colunas em uma ordem diferente da que naturalmente as temos
  3. Quer que eles sejam chamados de algo diferente do que temos armazenado ("Nº do cliente" vs "Número do cliente", por exemplo)

A intenção é facilitar o esforço necessário para acomodar essas solicitações de personalização. Atualmente, estamos em uma posição com algumas centenas de instâncias desses relatórios basicamente idênticos (excluindo essas diferenças superficiais). Eu estou olhando para ver se eu precisava de uma instância dessas Dynamicconsultas base por Parameterconjunto ou se eu poderia lidar com todos os parameterconjuntos possíveis por meio de 1 Stored Procedure. A esperança é também não ter que ter um monte de instâncias específicas de algum tipo de SSRS RDLarquivo ou SSIS DTSXpacote para lidar com essas mudanças. Que os dados saiam da Stored Procedureforma que precisamos que sejam exibidos/apresentados.

Vamos supor que eu construo um Dynamic SQL Commandonde a saída se parece com:

SELECT
Col1 AS 'Alias1',
Col2 AS 'Alias2',
Col3 AS 'Alias3'
FROM View
WHERE DateCol >= @StartDate
AND DateCol < @EndDate

Ele é construído a partir de algumas partes diferentes usando algumas tabelas. As estruturas de tabela abaixo são mais pseudocódigos para transmitir as ideias, então ignore coisas como não há chaves primárias declaradas, etc ...

CREATE TABLE [report].[ReportTemplate]
(
    ID INT NOT NULL, --(Primary Key)
    ReportName VarChar(100) NOT NULL,
    ReportTypeID INT NOT NULL --(FK To report.ReportTemplateType.ID)
)

CREATE TABLE [report].[ReportTemplateType]
(
    ID INT NOT NULL, --(Primary Key)
    Name VarChar(50), --(Unique Constraint)
    BaseCommand VarChar(2000), --Holds FROM and JOIN clauses
    WhereCommand VarChar(2000), --Holds WHERE Clause
    WhereCommandParameters VarChar(2000), --Holds declaration of the parameters
)

CREATE TABLE [report].[ReportTemplateColumnDetails]
(
    ID INT NOT NULL, --(Primary Key)
    ReportTemplateID INT NOT NULL, --(FK to report.ReportTemplate.ID)
    ColumnName VarChar(256) NOT NULL,
    ColumnAlias VarChar(256) NULL, --Have logic handle blank vs NULL values
    ColumnOrder SmallInt NOT NULL
)
+----+-------------------+--------------+
| ID |    ReportName     | ReportTypeID |
+----+-------------------+--------------+
|  1 | Customer 1 Status |            1 |
|  2 | Customer 1 Sales  |            2 |
+----+-------------------+--------------+


+----+--------+-----------------+------------------------------------------------------------------------------+-------------------------------------------------------------------+
| ID |  Name  |   BaseCommand   |                                WhereCondition                                |                     WhereConditionParameters                      |
+----+--------+-----------------+------------------------------------------------------------------------------+-------------------------------------------------------------------+
|  1 | Status | FROM StatusView | WHERE DateCol >= @StartDate AND DateCol < @EndDate                           | @StartDate DATEIME, @EndDate DateTime                             |
|  2 | Sales  | FROM SalesView  | WHERE DateCol >= @StartDate AND DateCol < @EndDate AND Col4 = @TypeParameter | @StartDate DATEIME, @EndDate DateTime, @TypeParameter VarChar(20) |
+----+--------+-----------------+------------------------------------------------------------------------------+-------------------------------------------------------------------+

+----+------------------+------------+-------------+-------------+
| ID | ReportTemplateID | ColumnName | ColumnAlias | ColumnOrder |
+----+------------------+------------+-------------+-------------+
|  1 |                1 | Col1       | Alias1      |           1 |
|  2 |                1 | Col2       | Alias2      |           2 |
|  3 |                1 | Col3       | Alias3      |           3 |
|  4 |                2 | Col4       | Alias1      |           1 |
|  5 |                2 | Col5       | Alias2      |           2 |
|  6 |                2 | Col6       | Alias3      |           3 |
+----+------------------+------------+-------------+-------------+

O comando é construído usando o código abaixo:

CREATE PROCEDURE [report].[ExecuteReportTemplate] (@ReportName VarChar(50))
AS
BEGIN
    DECLARE @SQLCommand VarChar(MAX) = 'SELECT ',
            @FirstColumnAdded BIT = 0,
            @BaseCommand VarChar(2000),
            @WhereCondition VarChar(2000),
            @WhereConditionParameters VarChar(2000)

    SELECT @BaseCommand = RTT.BaseCommand,
    @WhereCondition = RTT.WhereCommand, 
    @WhereConditionParameters = RTT.WhereCommandParameters 
    FROM [report].[ReportTemplateType] RTT
        INNER JOIN [report].[ReportTemplate] RT
            ON RTT.ID = RT.ReportTypeID
    WHERE RT.Name = @ReportName

    DECLARE @ColumnName VarChar(256),
            @ColumnAlias VarChar(256)

    DECLARE ColumnCursor CURSOR FOR
    SELECT ColumnName,
    ColumnAlias
    FROM [report].[ReportTemplateColumnDetails]
    ORDER BY ColumnOrder

    FETCH NEXT FROM ColumnCursor INTO @ColumnName, @ColumnAlias

    WHILE (@@FETCH_STATUS = 0)
    BEGIN
        --Add a comma inbetween columns, does not happen on the first one
        IF(@FirstColumnAdded = 1)
        BEGIN
            SET @SQLCommand = @SQLCommand + ', '
        END
        ELSE
        BEGIN
            SET @FirstColumnAdded = 1
        END

        --Adds the column into the list
        SET @SQLCommand = @SQLCommand + @ColumnName

        --If we have been provided an alias, set the alias
        IF(@ColumnAlias IS NULL OR LTRIM(RTRIM(@ColumnAlias)) = '')
        BEGIN
            @SQLCommand = @SQLCommand + 'AS ''' + @ColumnAlias + ''' '
        END
    END

    CLOSE ColumnCursor
    DEALLOCATE ColumnCursor

    --Now Add The Base Command
    SELECT @SQLCommand = @SQLCommand + ' ' + @BaseCommand + ' ' + @WhereCommand

    EXECUTE sp_executesql @sqlCommand, @WhereConditionParameters
        @StartDate = '2019-01-01', 
        @EndDate = GETDATE()
END

Existe uma maneira de alterar dinamicamente os parâmetros configurados e passados ​​sem ter que criar um comando separado?

Eu gostaria de ser capaz de preencher [report].[ReportTemplateType].[WhereCondition]e [report].[ReportTemplateType].[WhereCondition]com um diferente WHEREe Parameters. Por exemplo, adicionar um terceiro columnem WHERE conditionalgo como Col4 = @TypeParameter. A única maneira que conheço de resolver isso é criar um diferente Stored Procedureonde tudo seja idêntico ao acima Stored Procedure, mas mudaríamos a última peça para:

EXECUTE sp_executesql @sqlCommand, @WhereConditionParameters
        @StartDate = '2019-01-01', 
        @EndDate = GETDATE(),
        @TypeParameter = 'SomeStringValue'

Existe uma maneira de alterar dinamicamente os parâmetros configurados e passados ​​sem ter que criar um comando separado?

sql-server dynamic-sql
  • 3 respostas
  • 191 Views
Martin Hope
Kirk Saunders
Asked: 2019-06-21 06:54:26 +0800 CST

Lógica de decisão aninhada reutilizada - CTE versus código de cópia

  • 3

Pergunta

Eu tenho uma consulta que gera um column, criado por meio de uma série de CASEinstruções. Esse mesmo columné usado como parte de uma CASElógica para um 2º columnna mesma SELECTinstrução.

Se eu construísse um CTEcom a lógica interna aplicada para poder referenciar a lógica interna quando tiver que usá-la como uma decisão mais tarde. Qual é a sobrecarga geral adicional?

Pelo que entendi, não há nenhuma sobrecarga real adicionada. (Algumas pesquisas e um caso de teste simples que usei estão abaixo). Existem artigos que falam sobre isso ou casos em que não é o caso?


Pesquisa e Caso de Teste Simples

Encontrei alguns artigos que não indicam essa pergunta específica, mas me enviam na direção de que não há sobrecarga operacional adicionada.

  • https://www.scarydba.com/2016/07/18/common-table-expression-just-a-name/
  • https://www.sqlshack.com/why-is-my-cte-so-slow/

Eu escrevi uma pequena consulta em um de nossos bancos de dados existentes para testar essa teoria. Os resultados e os tempos de execução foram os mesmos, assim como The statisticse o Query Execution Plan.

Code, Execution Plane Statisticspara não CTE-versão:

SELECT PC.CompanyID,
PC.ClientID,
PC.ProgramID,
PC.PatientID,
PC.CaseID,
CASE
    WHEN PFH.FulFilHdrCreateDateTime IS NULL
        THEN PC.CaseCreateDateTime
    ELSE
        PFH.FulFilHdrCreateDateTime
    END AS [ImportantDate],
DATEDIFF(Day, CASE WHEN PFH.FulFilHdrCreateDateTime IS NULL THEN PC.CaseCreateDateTime ELSE PFH.FulFilHdrCreateDateTime END, GETDATE())
FROM PATIENTCASES PC
    LEFT OUTER JOIN PATFULFILLMENTHEADER PFH
        ON PFH.CompanyID = PC.CompanyID
        AND PFH.ClientID = PC.ClientID
        AND PFH.ProgramID = PC.ProgramID
        AND PFH.PatientID = PC.PatientID
        AND PFH.CaseID = PC.CaseID
        AND PFH.FulFilHdrID = (SELECT TOP(1) temp.FulFilHdrID
                                FROM PATFULFILLMENTHEADER temp
                                WHERE temp.CompanyID = PC.CompanyID
                                AND temp.ClientID = PC.ClientID
                                AND temp.ProgramID = PC.ProgramID
                                AND temp.PatientID = PC.PatientID
                                AND temp.CaseID = PC.CaseID
                                ORDER BY temp.FulFilHdrID
                            )
WHERE PC.CompanyID = 'RxCRoads'

Plano de Execução Não-CTE

+---------------------------------------------------------+----------+
| Query Profile Statistics                                |          |
|   Number of INSERT, DELETE and UPDATE statements        | 0        |
|   Rows affected by INSERT, DELETE, or UPDATE statements | 0        |
|   Number of SELECT statements                           | 2        |
|   Rows returned by SELECT statements                    | 2880384  |
|   Number of transactions                                | 0        |
| Network Statistics                                      |          |
|   Number of server roundtrips                           | 3        |
|   TDS packets sent from client                          | 3        |
|   TDS packets received from server                      | 38523    |
|   Bytes sent from client                                | 2128     |
|   Bytes received from server                            | 157781300|
| Time Statistics                                         |          |
|   Client processing time                                | 10158    |
|   Total execution time                                  | 10158    |
|   Wait time on server replies                           | 0        |
+---------------------------------------------------------+----------+

Code, Execution Plane Statisticspara a versão CTE:

WITH CTE (CompanyID, ClientID, ProgramID, PatientID, CaseID, ImportantDate)
AS
(
    SELECT PC.CompanyID,
    PC.ClientID,
    PC.ProgramID,
    PC.PatientID,
    PC.CaseID,
    CASE
        WHEN PFH.FulFilHdrCreateDateTime IS NULL
            THEN PC.CaseCreateDateTime
        ELSE
            PFH.FulFilHdrCreateDateTime
        END AS [ImportantDate]
    FROM PATIENTCASES PC
        LEFT OUTER JOIN PATFULFILLMENTHEADER PFH
            ON PFH.CompanyID = PC.CompanyID
            AND PFH.ClientID = PC.ClientID
            AND PFH.ProgramID = PC.ProgramID
            AND PFH.PatientID = PC.PatientID
            AND PFH.CaseID = PC.CaseID
            AND PFH.FulFilHdrID = (SELECT TOP(1) temp.FulFilHdrID
                                    FROM PATFULFILLMENTHEADER temp
                                    WHERE temp.CompanyID = PC.CompanyID
                                    AND temp.ClientID = PC.ClientID
                                    AND temp.ProgramID = PC.ProgramID
                                    AND temp.PatientID = PC.PatientID
                                    AND temp.CaseID = PC.CaseID
                                    ORDER BY temp.FulFilHdrID
                                )
)
SELECT CompanyID, 
ClientID, 
ProgramID, 
PatientID, 
CaseID, 
ImportantDate,
DATEDIFF(Day, [ImportantDate], GETDATE())
FROM CTE
WHERE CompanyID = 'RxCRoads'

Plano de Execução CTE

+---------------------------------------------------------+-----------+
| Query Profile Statistics                                |           |
|   Number of INSERT, DELETE and UPDATE statements        |         0 |
|   Rows affected by INSERT, DELETE, or UPDATE statements |         0 |
|   Number of SELECT statements                           |         2 |
|   Rows returned by SELECT statements                    |   2880383 |
|   Number of transactions                                |         0 |
| Network Statistics                                      |           |
|   Number of server roundtrips                           |         3 |
|   TDS packets sent from client                          |         3 |
|   TDS packets received from server                      |     38523 |
|   Bytes sent from client                                |      2348 |
|   Bytes received from server                            | 157781800 |
| Time Statistics                                         |           |
|   Client processing time                                |      9985 |
|   Total execution time                                  |      9985 |
|   Wait time on server replies                           |         0 |
+---------------------------------------------------------+-----------+
sql-server performance
  • 1 respostas
  • 130 Views
Martin Hope
Kirk Saunders
Asked: 2019-06-07 06:37:41 +0800 CST

SQL Server - Design de tabela física - Ordem das colunas - Colunas nulas e não nulas

  • 1

Estamos no processo de construção de um banco de dados para um novo aplicativo. Recebi alguns comentários do arquiteto de que ele leu em algum lugar que há um benefício de utilização de memória por ter todas as colunas não anuláveis ​​em uma tabela primeiro, depois todas as colunas anuláveis. Se houver colunas anuláveis ​​entre colunas não anuláveis, algum tipo de benefício de memória ou armazenamento será perdido porque essas colunas anuláveis ​​estão entre colunas não anuláveis.

As colunas foram ordenadas em uma ordem ligeiramente ambígua, mas em geral foi priorizada para colunas que eram mais prováveis ​​de serem usadas primeiro.

Fiquei com a impressão de que o SSMS ordena as colunas no arquivo de paginação por sua própria lógica, em vez da ordem específica em que são criadas na tabela. Que a ordem em que coloquei as colunas na tabela era totalmente independente de como os dados eram armazenados no arquivo de paginação.

Existe alguma documentação em algum lugar que apoiaria essa descoberta/compreensão?

EDITAR:

Ter mais algumas conversas sobre descobrir de onde veio essa ideia. A solicitação foi uma simplificação excessiva de ter alta densidade de dados ou colunas usadas com mais frequência SELECTou JOINoperações na frente da tabela para impedir que eles fossem movidos para a seção Estouro do arquivo de página.

Que a ordem das colunas atribuídas à tabela seja a mesma ordem em que os dados são adicionados ao arquivo de paginação. Para uma determinada linha, os dados são armazenados no arquivo de paginação na ordem em que as colunas são definidas na tabela. Se a linha contém mais dados do que o arquivo de paginação permite (assumindo que não estamos usando nada que vá para um LOB IMAGEou VARCHAR(MAX)algo assim), o restante é colocado no arquivo de estouro. Se esses dados de estouro forem necessários, haverá esforço extra e tempo gasto fazendo a pesquisa para esse arquivo de estouro. Isso pode resultar em impactos perceptíveis no desempenho em ambientes de alta linha (10 ou 100 de milhões de linhas +). Portanto, gostaríamos de priorizar a ordem das colunas em quantas vezes achamos que a coluna será acessada, não necessariamente se é NULLou não.

Essa compreensão/análise parece correta?

sql-server database-design
  • 2 respostas
  • 364 Views
Martin Hope
Kirk Saunders
Asked: 2018-12-04 07:11:50 +0800 CST

Estrutura de bloqueio de tabela/linha de back-end usando consultas CTE

  • 2

Esta pergunta é uma extensão de uma pergunta anterior que fiz. Bloqueio de tabela ao usar uniões

Com a mesma consulta que estamos usando que está causando o bloqueio das várias consultas usadas, essas UNIONSsão as consultas CTE.

Por exemplo:

CREATE TABLE #TempTable (
    [Columns]
)

WITH CTE1 (Columns)
(
    Select [Columns] FROM [Tables] WHERE [WHERE-Condition]
),
CTE2 (Columns)
(
    Select [Columns] FROM [Tables] WHERE [WHERE-Condition]
),
CTE3 (Columns)
(
    Select [Columns] FROM [Tables] WHERE [WHERE-Condition]
),
CTE4 (Columns)
(
    Select [Columns] FROM [Tables] WHERE [WHERE-Condition]
),
CTE5 (Columns)
(
    Select [Columns] FROM [Tables] WHERE [WHERE-Condition]
),
CTE6 (Columns)
(
    Select [Columns] FROM [Tables] WHERE [WHERE-Condition]
),
CTE7 (Columns)
(
    Select [Columns] FROM [Tables] WHERE [WHERE-Condition]
)

INSERT INTO #TempTable
SELECT * FROM CTE1
UNION
SELECT * FROM CTE2
UNION
SELECT * FROM CTE3
UNION
SELECT * FROM CTE4
UNION
SELECT * FROM CTE5
UNION
SELECT * FROM CTE6 WHERE [Where-Condition]
UNION
SELECT * FROM CTE7

Assumindo este cenário específico (e não temos nenhuma transação explícita declarada) a estrutura de bloqueio da tabela física muda, porque estamos usando consultas CTE?

Quando o SELECTfor CTE1 é concluído como parte do UNION, as tabelas físicas ainda estão bloqueadas ou os bloqueios ainda estão liberados?

Com base na resposta da minha pergunta anterior, fiquei com a impressão de que, no contexto de a, UNIONquando o SELECTpara uma das várias SELECTdeclarações completas, as tabelas são liberadas. Isso é incorreto?

Não modificamos o nível de isolamento para esta transação. Pelo que entendi, isso significa que estamos usando READ_COMMITTED. A questão ainda é aplicável com apenas 2 SELECTdeclarações. Estou tentando entender como funciona essa funcionalidade. A consulta específica com a qual estou trabalhando usa 7, que é a única razão pela qual especifiquei 7.

sql-server sql-server-2012
  • 1 respostas
  • 1078 Views
Martin Hope
Kirk Saunders
Asked: 2018-12-01 10:17:53 +0800 CST

Bloqueio de tabela ao usar uniões

  • 2

Quando várias seleções são usadas em um UNION/UNION ALL, os bloqueios de tabela para cada SELECTinstrução individual são tratados individualmente ou todos os bloqueios de tabela são mantidos até que todas as SELECTinstruções sejam concluídas?

Por exemplo, 100 instruções de seleção individuais são concatenadas por meio de UNION/UNION ALL. (Supondo que eles sejam resolvidos sequencialmente) Se a primeira SELECTtransação for concluída e outra transação em uma sessão diferente tentar acessar os mesmos dados, os dados ainda estarão bloqueados pelo UNION?

Estou apenas tentando entender como UNIONsse comportar com as tabelas físicas enquanto elas ainda estão em execução.

Para a consulta que levou a isso, existem 7 declarações diferentes no UNION(Not UNION ALL). Com essa pergunta em particular, eu estava apenas querendo entender a arquitetura de back-end de como UNION/UNION ALLfuncionava. A consulta que gerou essa pergunta causa muito bloqueio, mas é executada apenas por cerca de um minuto, então eu estava tentando entender se era a consulta inteira que causava isso ou apenas algumas das partes individuais.

Eu adicionei uma pergunta de acompanhamento aqui: Estrutura de bloqueio de tabela/linha de back-end usando consultas CTE

sql-server sql-server-2012
  • 1 respostas
  • 987 Views
Martin Hope
Kirk Saunders
Asked: 2016-04-19 11:00:27 +0800 CST

Instrução de mesclagem SQL gastando muito tempo classificando na chave primária

  • 3

Estamos procurando usar a instrução SQL MERGE no SQL Server 2012 para lidar com a replicação de dados para um data warehouse ao qual temos acesso do fabricante de um aplicativo de terceiros que usamos para entrada de dados.

A origem do data warehouse é um ambiente Oracle e estamos usando o SQL Connector para fazer referência ao banco de dados Oracle em nosso ambiente como um servidor vinculado. Os dados são carregados/atualizados na fonte de dados Oracle em um dump noturno.

Estamos analisando a instrução MERGE devido à falta de confiabilidade/instabilidade que vimos com a replicação transacional e de instantâneo.

Abaixo está a estrutura da tabela para fazer a mesclagem:

    CREATE TABLE [dbo].[FACT_WIP_2](
    [WIP_KEY] [float] NOT NULL,
    [PATIENT_KEY] [float] NULL,
    [PHARMACY_KEY] [float] NULL,
    [LINE_PHARM_KEY] [float] NULL,
    [DELIVERY_ADDRESS_KEY] [float] NULL,
    [INVENTORY_TYPE_KEY] [float] NULL,
    [PHYSICIAN_LOCATION_KEY] [float] NULL,
    [PRIMARY_ORIGINAL_INS_PLAN_KEY] [float] NULL,
    [PRIMARY_INSURANCE_PLAN_KEY] [float] NULL,
    [REFERRAL_PRIORITY_KEY] [float] NULL,
    [REIMBURSEMENT_STATUS_REF_KEY] [float] NULL,
    [REIMBURSEMENT_STATUS_STAGE_KEY] [float] NULL,
    [REFERRAL_SOURCE_TYPE_KEY] [float] NULL,
    [REFERRAL_START_DATE_KEY] [float] NULL,
    [STAGE_START_DATE_KEY] [float] NULL,
    [STAGE_END_DATE_KEY] [float] NULL,
    [ASSIGNED_EMPLOYEE_KEY] [float] NULL,
    [REFERRAL_COMPLETION_DATE_KEY] [float] NULL,
    [REFERRAL_CYCLE_KEY] [float] NULL,
    [SHIP_DATE_KEY] [float] NULL,
    [SHIP_MODE_KEY] [float] NULL,
    [PLACE_OF_SERVICE_KEY] [float] NULL,
    [REF_BUSINESS_DRIVERS_KEY] [float] NULL,
    [REF_OUTCOME_STATUS_KEY] [float] NULL,
    [STAGE_OUTCOME_STATUS_KEY] [float] NULL,
    [REF_REFERENCE_CATEGORY_KEY] [float] NULL,
    [THERAPY_GROUP_KEY] [float] NULL,
    [FORWARD_REASON_KEY] [float] NULL,
    [FORWARDED_TO_PHARMACY_KEY] [float] NULL,
    [IMAGE_RECEIPT_DATE_KEY] [float] NULL,
    [DATA_SOURCE_KEY] [float] NULL,
    [ORDER_START_DATE_KEY] [float] NULL,
    [DRUG_KEY] [float] NULL,
    [WORK_STAGE_KEY] [float] NULL,
    [REFERRAL_NEED_DATE_KEY] [float] NULL,
    [ORDER_NEED_DATE_KEY] [float] NULL,
    [WIP_TYPE] [varchar](1) NULL,
    [REFERRAL_ID] [varchar](32) NULL,
    [REFERRAL_LINE_NUM] [float] NULL,
    [ORDER_ID] [varchar](150) NULL,
    [ORDER_LINE_NUM] [float] NULL,
    [DIAGNOSIS_CODE] [varchar](10) NULL,
    [DIAGNOSIS_DESCRIPTION] [varchar](40) NULL,
    [QTY_WRITTEN] [float] NULL,
    [METRIC_QTY] [float] NULL,
    [DELETED_VOID_INDICATOR] [varchar](1) NULL,
    [DAY_SUPPLY] [float] NULL,
    [PROFILED_RX_INDICATOR] [numeric](1, 0) NULL,
    [PAT_PRIMARY_INS_CARDHOLDER_ID] [varchar](20) NULL,
    [PAT_PRIMARY_INS_EMPLOYER] [varchar](30) NULL,
    [PAT_PRIMARY_INS_GROUP_NUMBER] [varchar](30) NULL,
    [RX_NUMBER] [float] NULL,
    [REFILL_NUMBER] [float] NULL,
    [REFERRAL_START_TIMESTAMP] [datetime] NULL,
    [STAGE_START_TIMESTAMP] [datetime] NULL,
    [STAGE_END_TIMESTAMP] [datetime] NULL,
    [WORK_STAGE_ASSIGN_STATUS] [varchar](10) NULL,
    [REFERRAL_COMPLETION_TIMESTAMP] [datetime] NULL,
    [ORDER_START_TIMESTAMP] [datetime] NULL,
    [PRIOR_AUTH_APPEAL_INDICATOR] [varchar](20) NULL,
    [BV_MISSING_INFO_INDICATOR] [numeric](1, 0) NULL,
    [ORDER_COMPLETION_TIMESTAMP] [datetime] NULL,
    [SUPPLY_ITEM_INDICATOR] [numeric](1, 0) NULL,
    [FORWARDED_REFERRAL_INDICATOR] [numeric](1, 0) NULL,
    [NOGO_INDICATOR] [numeric](1, 0) NULL,
    [CREATE_UPDATE_DATE] [datetime] NULL,
    [ORDER_STATUS] [varchar](50) NULL,
    [REFERRAL_STATUS] [varchar](50) NULL,
    [VIRTUAL_STAGE_OUTCOME] [varchar](40) NULL,
    [VIRTUAL_STAGE_OUTCOME_REASON] [varchar](40) NULL,
    [UNIQUE_ID] [varchar](250) NULL,
    [STAGED_DATE_TIMESTAMP] [datetime] NULL,
    [REWORK_COUNT] [float] NULL,
 CONSTRAINT [MSHREPL_290_PK_2] PRIMARY KEY CLUSTERED 
    (
        [WIP_KEY] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]

E esta é a consulta que estamos usando para concluir nossa mesclagem:

MERGE FACT_WIP_2 AS S
USING RXCSMAP..SMA.FACT_WIP AS O
ON (S.WIP_KEY = O.WIP_KEY)
WHEN MATCHED
AND O.CREATE_UPDATE_DATE > @DateToStartLooking
AND O.CREATE_UPDATE_DATE <> S.CREATE_UPDATE_DATE
THEN
UPDATE 
SET 
S.PATIENT_KEY = O.PATIENT_KEY,
S.PHARMACY_KEY = O.PHARMACY_KEY,
S.LINE_PHARM_KEY = O.LINE_PHARM_KEY,
S.DELIVERY_ADDRESS_KEY = O.DELIVERY_ADDRESS_KEY,
S.INVENTORY_TYPE_KEY = O.INVENTORY_TYPE_KEY,
S.PHYSICIAN_LOCATION_KEY = O.PHYSICIAN_LOCATION_KEY,
S.PRIMARY_ORIGINAL_INS_PLAN_KEY = O.PRIMARY_ORIGINAL_INS_PLAN_KEY,
S.PRIMARY_INSURANCE_PLAN_KEY = O.PRIMARY_INSURANCE_PLAN_KEY,
S.REFERRAL_PRIORITY_KEY = O.REFERRAL_PRIORITY_KEY,
S.REIMBURSEMENT_STATUS_REF_KEY = O.REIMBURSEMENT_STATUS_REF_KEY,
S.REIMBURSEMENT_STATUS_STAGE_KEY = O.REIMBURSEMENT_STATUS_STAGE_KEY,
S.REFERRAL_SOURCE_TYPE_KEY = O.REFERRAL_SOURCE_TYPE_KEY,
S.REFERRAL_START_DATE_KEY = O.REFERRAL_START_DATE_KEY,
S.STAGE_START_DATE_KEY = O.STAGE_START_DATE_KEY,
S.STAGE_END_DATE_KEY = O.STAGE_END_DATE_KEY,
S.ASSIGNED_EMPLOYEE_KEY = O.ASSIGNED_EMPLOYEE_KEY,
S.REFERRAL_COMPLETION_DATE_KEY = O.REFERRAL_COMPLETION_DATE_KEY,
S.REFERRAL_CYCLE_KEY = O.REFERRAL_CYCLE_KEY,
S.SHIP_DATE_KEY = O.SHIP_DATE_KEY,
S.SHIP_MODE_KEY = O.SHIP_MODE_KEY,
S.PLACE_OF_SERVICE_KEY = O.PLACE_OF_SERVICE_KEY,
S.REF_BUSINESS_DRIVERS_KEY = O.REF_BUSINESS_DRIVERS_KEY,
S.REF_OUTCOME_STATUS_KEY = O.REF_OUTCOME_STATUS_KEY,
S.STAGE_OUTCOME_STATUS_KEY = O.STAGE_OUTCOME_STATUS_KEY,
S.REF_REFERENCE_CATEGORY_KEY = O.REF_REFERENCE_CATEGORY_KEY,
S.THERAPY_GROUP_KEY = O.THERAPY_GROUP_KEY,
S.FORWARD_REASON_KEY = O.FORWARD_REASON_KEY,
S.FORWARDED_TO_PHARMACY_KEY = O.FORWARDED_TO_PHARMACY_KEY,
S.IMAGE_RECEIPT_DATE_KEY = O.IMAGE_RECEIPT_DATE_KEY,
S.DATA_SOURCE_KEY = O.DATA_SOURCE_KEY,
S.ORDER_START_DATE_KEY = O.ORDER_START_DATE_KEY,
S.DRUG_KEY = O.DRUG_KEY,
S.WORK_STAGE_KEY = O.WORK_STAGE_KEY,
S.REFERRAL_NEED_DATE_KEY = O.REFERRAL_NEED_DATE_KEY,
S.ORDER_NEED_DATE_KEY = O.ORDER_NEED_DATE_KEY,
S.WIP_TYPE = O.WIP_TYPE,
S.REFERRAL_ID = O.REFERRAL_ID,
S.REFERRAL_LINE_NUM = O.REFERRAL_LINE_NUM,
S.ORDER_ID = O.ORDER_ID,
S.ORDER_LINE_NUM = O.ORDER_LINE_NUM,
S.DIAGNOSIS_CODE = O.DIAGNOSIS_CODE,
S.DIAGNOSIS_DESCRIPTION = O.DIAGNOSIS_DESCRIPTION,
S.QTY_WRITTEN = O.QTY_WRITTEN,
S.METRIC_QTY = O.METRIC_QTY,
S.DELETED_VOID_INDICATOR = O.DELETED_VOID_INDICATOR,
S.DAY_SUPPLY = O.DAY_SUPPLY,
S.PROFILED_RX_INDICATOR = O.PROFILED_RX_INDICATOR,
S.PAT_PRIMARY_INS_CARDHOLDER_ID = O.PAT_PRIMARY_INS_CARDHOLDER_ID,
S.PAT_PRIMARY_INS_EMPLOYER = O.PAT_PRIMARY_INS_EMPLOYER,
S.PAT_PRIMARY_INS_GROUP_NUMBER = O.PAT_PRIMARY_INS_GROUP_NUMBER,
S.RX_NUMBER = O.RX_NUMBER,
S.REFILL_NUMBER = O.REFILL_NUMBER,
S.REFERRAL_START_TIMESTAMP = O.REFERRAL_START_TIMESTAMP,
S.STAGE_START_TIMESTAMP = O.STAGE_START_TIMESTAMP,
S.STAGE_END_TIMESTAMP = O.STAGE_END_TIMESTAMP,
S.WORK_STAGE_ASSIGN_STATUS = O.WORK_STAGE_ASSIGN_STATUS,
S.REFERRAL_COMPLETION_TIMESTAMP = O.REFERRAL_COMPLETION_TIMESTAMP,
S.ORDER_START_TIMESTAMP = O.ORDER_START_TIMESTAMP,
S.PRIOR_AUTH_APPEAL_INDICATOR = O.PRIOR_AUTH_APPEAL_INDICATOR,
S.BV_MISSING_INFO_INDICATOR = O.BV_MISSING_INFO_INDICATOR,
S.ORDER_COMPLETION_TIMESTAMP = O.ORDER_COMPLETION_TIMESTAMP,
S.SUPPLY_ITEM_INDICATOR = O.SUPPLY_ITEM_INDICATOR,
S.FORWARDED_REFERRAL_INDICATOR = O.FORWARDED_REFERRAL_INDICATOR,
S.NOGO_INDICATOR = O.NOGO_INDICATOR,
S.CREATE_UPDATE_DATE = O.CREATE_UPDATE_DATE,
S.ORDER_STATUS = O.ORDER_STATUS,
S.REFERRAL_STATUS = O.REFERRAL_STATUS,
S.VIRTUAL_STAGE_OUTCOME = O.VIRTUAL_STAGE_OUTCOME,
S.VIRTUAL_STAGE_OUTCOME_REASON = O.VIRTUAL_STAGE_OUTCOME_REASON,
S.UNIQUE_ID = O.UNIQUE_ID,
S.STAGED_DATE_TIMESTAMP = O.STAGED_DATE_TIMESTAMP,
S.REWORK_COUNT = O.REWORK_COUNT
--When no records are matched, insert
--the incoming records from Oracle Table
--to our SQL environment table
WHEN NOT MATCHED BY TARGET THEN
INSERT 
(
    WIP_KEY,
    PATIENT_KEY,
    PHARMACY_KEY,
    LINE_PHARM_KEY,
    DELIVERY_ADDRESS_KEY,
    INVENTORY_TYPE_KEY,
    PHYSICIAN_LOCATION_KEY,
    PRIMARY_ORIGINAL_INS_PLAN_KEY,
    PRIMARY_INSURANCE_PLAN_KEY,
    REFERRAL_PRIORITY_KEY,
    REIMBURSEMENT_STATUS_REF_KEY,
    REIMBURSEMENT_STATUS_STAGE_KEY,
    REFERRAL_SOURCE_TYPE_KEY,
    REFERRAL_START_DATE_KEY,
    STAGE_START_DATE_KEY,
    STAGE_END_DATE_KEY,
    ASSIGNED_EMPLOYEE_KEY,
    REFERRAL_COMPLETION_DATE_KEY,
    REFERRAL_CYCLE_KEY,
    SHIP_DATE_KEY,
    SHIP_MODE_KEY,
    PLACE_OF_SERVICE_KEY,
    REF_BUSINESS_DRIVERS_KEY,
    REF_OUTCOME_STATUS_KEY,
    STAGE_OUTCOME_STATUS_KEY,
    REF_REFERENCE_CATEGORY_KEY,
    THERAPY_GROUP_KEY,
    FORWARD_REASON_KEY,
    FORWARDED_TO_PHARMACY_KEY,
    IMAGE_RECEIPT_DATE_KEY,
    DATA_SOURCE_KEY,
    ORDER_START_DATE_KEY,
    DRUG_KEY,
    WORK_STAGE_KEY,
    REFERRAL_NEED_DATE_KEY,
    ORDER_NEED_DATE_KEY,
    WIP_TYPE,
    REFERRAL_ID,
    REFERRAL_LINE_NUM,
    ORDER_ID,
    ORDER_LINE_NUM,
    DIAGNOSIS_CODE,
    DIAGNOSIS_DESCRIPTION,
    QTY_WRITTEN,
    METRIC_QTY,
    DELETED_VOID_INDICATOR,
    DAY_SUPPLY,
    PROFILED_RX_INDICATOR,
    PAT_PRIMARY_INS_CARDHOLDER_ID,
    PAT_PRIMARY_INS_EMPLOYER,
    PAT_PRIMARY_INS_GROUP_NUMBER,
    RX_NUMBER,
    REFILL_NUMBER,
    REFERRAL_START_TIMESTAMP,
    STAGE_START_TIMESTAMP,
    STAGE_END_TIMESTAMP,
    WORK_STAGE_ASSIGN_STATUS,
    REFERRAL_COMPLETION_TIMESTAMP,
    ORDER_START_TIMESTAMP,
    PRIOR_AUTH_APPEAL_INDICATOR,
    BV_MISSING_INFO_INDICATOR,
    ORDER_COMPLETION_TIMESTAMP,
    SUPPLY_ITEM_INDICATOR,
    FORWARDED_REFERRAL_INDICATOR,
    NOGO_INDICATOR,
    CREATE_UPDATE_DATE,
    ORDER_STATUS,
    REFERRAL_STATUS,
    VIRTUAL_STAGE_OUTCOME,
    VIRTUAL_STAGE_OUTCOME_REASON,
    UNIQUE_ID,
    STAGED_DATE_TIMESTAMP,
    REWORK_COUNT
)
VALUES
(
    O.WIP_KEY,
    O.PATIENT_KEY,
    O.PHARMACY_KEY,
    O.LINE_PHARM_KEY,
    O.DELIVERY_ADDRESS_KEY,
    O.INVENTORY_TYPE_KEY,
    O.PHYSICIAN_LOCATION_KEY,
    O.PRIMARY_ORIGINAL_INS_PLAN_KEY,
    O.PRIMARY_INSURANCE_PLAN_KEY,
    O.REFERRAL_PRIORITY_KEY,
    O.REIMBURSEMENT_STATUS_REF_KEY,
    O.REIMBURSEMENT_STATUS_STAGE_KEY,
    O.REFERRAL_SOURCE_TYPE_KEY,
    O.REFERRAL_START_DATE_KEY,
    O.STAGE_START_DATE_KEY,
    O.STAGE_END_DATE_KEY,
    O.ASSIGNED_EMPLOYEE_KEY,
    O.REFERRAL_COMPLETION_DATE_KEY,
    O.REFERRAL_CYCLE_KEY,
    O.SHIP_DATE_KEY,
    O.SHIP_MODE_KEY,
    O.PLACE_OF_SERVICE_KEY,
    O.REF_BUSINESS_DRIVERS_KEY,
    O.REF_OUTCOME_STATUS_KEY,
    O.STAGE_OUTCOME_STATUS_KEY,
    O.REF_REFERENCE_CATEGORY_KEY,
    O.THERAPY_GROUP_KEY,
    O.FORWARD_REASON_KEY,
    O.FORWARDED_TO_PHARMACY_KEY,
    O.IMAGE_RECEIPT_DATE_KEY,
    O.DATA_SOURCE_KEY,
    O.ORDER_START_DATE_KEY,
    O.DRUG_KEY,
    O.WORK_STAGE_KEY,
    O.REFERRAL_NEED_DATE_KEY,
    O.ORDER_NEED_DATE_KEY,
    O.WIP_TYPE,
    O.REFERRAL_ID,
    O.REFERRAL_LINE_NUM,
    O.ORDER_ID,
    O.ORDER_LINE_NUM,
    O.DIAGNOSIS_CODE,
    O.DIAGNOSIS_DESCRIPTION,
    O.QTY_WRITTEN,
    O.METRIC_QTY,
    O.DELETED_VOID_INDICATOR,
    O.DAY_SUPPLY,
    O.PROFILED_RX_INDICATOR,
    O.PAT_PRIMARY_INS_CARDHOLDER_ID,
    O.PAT_PRIMARY_INS_EMPLOYER,
    O.PAT_PRIMARY_INS_GROUP_NUMBER,
    O.RX_NUMBER,
    O.REFILL_NUMBER,
    O.REFERRAL_START_TIMESTAMP,
    O.STAGE_START_TIMESTAMP,
    O.STAGE_END_TIMESTAMP,
    O.WORK_STAGE_ASSIGN_STATUS,
    O.REFERRAL_COMPLETION_TIMESTAMP,
    O.ORDER_START_TIMESTAMP,
    O.PRIOR_AUTH_APPEAL_INDICATOR,
    O.BV_MISSING_INFO_INDICATOR,
    O.ORDER_COMPLETION_TIMESTAMP,
    O.SUPPLY_ITEM_INDICATOR,
    O.FORWARDED_REFERRAL_INDICATOR,
    O.NOGO_INDICATOR,
    O.CREATE_UPDATE_DATE,
    O.ORDER_STATUS,
    O.REFERRAL_STATUS,
    O.VIRTUAL_STAGE_OUTCOME,
    O.VIRTUAL_STAGE_OUTCOME_REASON,
    O.UNIQUE_ID,
    O.STAGED_DATE_TIMESTAMP,
    O.REWORK_COUNT
)
--When there is a row that exists in our SQL table and
--same record does not exist in Oracle table
--then delete this record from our SQL table
WHEN NOT MATCHED BY SOURCE
THEN
DELETE;

Eis o Plano de execução: Plano de execução

Que opções para configuração de consulta ou estrutura de tabela (índices, estatísticas, etc...) poderíamos fazer para tentar otimizar esse processo?

sql-server sql-server-2012
  • 1 respostas
  • 254 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