Usuário com melhor resposta
Performance com Where

Pergunta
-
Pessoal
Onde eu teria melhor performance de execução do script abaixo :
Opção 1) update tb_rec set tb_rec.ds_status = 'L' ,tb_rec.baixado = getdate() ,tb_rec.id_Bordero = @id_Bordero from nc_receber tb_rec inner join tbl_Transacao_Forma tb_for on tb_rec.ChaveControle = tb_for.id_Chave_Controle where tb_for.id_Transacao_Pagar = @id_Transacao_Bordero Opção 2) update tb_rec set tb_rec.ds_status = 'L' ,tb_rec.baixado = getdate() ,tb_rec.id_Bordero = @id_Bordero from nc_receber tb_rec inner join tbl_Transacao_Forma tb_for on tb_rec.ChaveControle = tb_for.id_Chave_Controle and tb_for.id_Transacao_Pagar = @id_Transacao_Bordero
Respostas
-
Deleted
- Marcado como Resposta Durval RamosModerator terça-feira, 8 de abril de 2014 18:10
-
Deleted
- Marcado como Resposta Durval RamosModerator terça-feira, 8 de abril de 2014 18:10
-
Junior
E na sua opinião entre os 2 script qual seria o melhor ?
Opção 2.1) update tb_rec set tb_rec.ds_status = 'L' ,tb_rec.baixado = getdate() ,tb_rec.id_Bordero = @id_Bordero from nc_receber tb_rec inner join tbl_Transacao_Forma tb_for on tb_rec.ChaveControle = tb_for.id_Chave_Controle where tb_for.id_Transacao_Pagar = @id_Transacao_Bordero Opção 2.2) update tb_rec set tb_rec.ds_status = 'L' ,tb_rec.baixado = getdate() ,tb_rec.id_Bordero = @id_Bordero from nc_receber where ChaveControle = (select id_Chave_Controle from tbl_Transacao_Forma where id_Transacao_Pagar = @id_Transacao)
Nei,
Complementando a informação do Junior, sua opção 2.1 é a melhor pela condição de processamento do comando UPDATE dentro do SQL Server.
Como referência, veja a documentação oficial do SQL Server para este comando (http://technet.microsoft.com/pt-br/library/ms177523.aspx#TableHints ) em especial à parte sobre Table Hint e o comando SELECT ( http://technet.microsoft.com/pt-br/library/ms189499.aspx ) onde à ordem de processamento lógico afeta a resolução e a performance da consulta, e consequentemente, afeta também os comandos DELETE e UPDATE da mesma forma. Segue abaixo a ordem de processamento lógico de uma instrução T-SQL:
1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. WITH CUBE OU WITH ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOPCom este conceito, podemos afirmar que é possível obter o resultado desejado de performance através de condições "ON" em detrimento do "WHERE". Em alguns casos o ganho de sua consulta pode ser significativo, mas para poucos registros pode ser insignificante.
Um modo que pode ajudar sua decisão para verificar exatamente qual comando UPDATE é mais vantajoso (de forma simples) utilize antes da instrução o comando:
SET STATISTICS TIME ON GO SET STATISTICS IO ON GO update tb_rec set tb_rec.ds_status = 'L' ,tb_rec.baixado = getdate() ,tb_rec.id_Bordero = @id_Bordero from nc_receber tb_rec inner join tbl_Transacao_Forma tb_for on tb_rec.ChaveControle = tb_for.id_Chave_Controle where tb_for.id_Transacao_Pagar = @id_Transacao_Bordero SET STATISTICS TIME OFF GO SET STATISTICS IO OFF GO
Espero que seja útil para você.
Abraços,
Durval RamosMicrosoft Partner | MTA - SQL Server 2012---------------------------------- Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"- Sugerido como Resposta Roberto F FonsecaModerator terça-feira, 24 de dezembro de 2013 20:02
- Marcado como Resposta Durval RamosModerator terça-feira, 8 de abril de 2014 18:10
Todas as Respostas
-
Deleted
- Marcado como Resposta Durval RamosModerator terça-feira, 8 de abril de 2014 18:10
-
Nei,
Identificar o melhor solução é algo que pode variar muito inclusive no mesmo cenário.
Eu particularmente gosto da segunda opção, ao meu ver ela é mais claro e legível, onde temos o From com as tabelas envolvidas e relacionadas e a clausula where como filtro para os nossos dados.
Você poderia compartilhar conosco a sua estrutura do seu ambiente?
A sugestão do José Diz para você consultar o Livro do Inside é fantástica, inclusive eu mesmo tenho este livro e faço uso do mesmo.
Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]
-
Junior
A estrutura é +/- esta abaixo, veja se ajuda na sua analise :
E a opção que você falou que seria melhor seria esta mesmo ?
-- código 2
update tb_rec
set tb_rec.ds_status = 'L'
,tb_rec.baixado = getdate()
,tb_rec.id_Bordero = @id_Bordero
from nc_receber
where ChaveControle =
(select id_Chave_Controle from tbl_Transacao_Forma where id_Transacao_Pagar = @id_Transacao
CREATE TABLE [dbo].[tbl_Transacao_Forma]( [id_Transacao_Pagar] [int] NOT NULL, [id_Chave_Controle] [int] NOT NULL, [id_Tipo_Pagto] [int] NOT NULL, [id_Forma_Pagto] [int] NOT NULL, [id_Banco] [int] NOT NULL, [nr_Documento] [char](10) NOT NULL, [nr_Seq_Documento] [int] NOT NULL, [dt_Vencto_Documento] [datetime] NOT NULL, [vl_Documento] [decimal](18, 2) NOT NULL ) ON [PRIMARY] CREATE TABLE [dbo].[nC_RECEBER]( [ChaveControle] [int] IDENTITY(1,1) NOT NULL, [referencia] [char](20) NOT NULL, [cadastro] [datetime] NULL, [sacadoprincipal] [int] NOT NULL, [vencimento] [datetime] NOT NULL, [valor] [decimal](18, 2) NOT NULL, [status] [char](1) NOT NULL, [codlancamento] [int] NULL, [vendas] [int] NULL, [operador] [int] NULL, [statusdocaixa] [int] NULL, [codvenda] [int] NULL, [baixado] [datetime] NULL, [nf] [char](9) NULL, [fatura] [char](12) NULL, [banco] [int] NOT NULL, [boleto] [char](20) NULL, [empresa] [int] NOT NULL, [id_Bordero] [int] NOT NULL ) ON [PRIMARY]
-
Neibala,
Na minha opinião sim, mais isso tem que ser analisado, mas um fator importante é o uso da clausula where para filtrar os dados, bem como, se as colunas declaradas no Where forem índices.
Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]
-
Junior
E na sua opinião entre os 2 script qual seria o melhor ?
Opção 2.1) update tb_rec set tb_rec.ds_status = 'L' ,tb_rec.baixado = getdate() ,tb_rec.id_Bordero = @id_Bordero from nc_receber tb_rec inner join tbl_Transacao_Forma tb_for on tb_rec.ChaveControle = tb_for.id_Chave_Controle where tb_for.id_Transacao_Pagar = @id_Transacao_Bordero Opção 2.2) update tb_rec set tb_rec.ds_status = 'L' ,tb_rec.baixado = getdate() ,tb_rec.id_Bordero = @id_Bordero from nc_receber where ChaveControle = (select id_Chave_Controle from tbl_Transacao_Forma where id_Transacao_Pagar = @id_Transacao)
-
Neibala,
Cara eu prefiro a opção 1.
Não gosto muito de ficar utilizar Subquery.
Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]
-
Junior
E na sua opinião entre os 2 script qual seria o melhor ?
Opção 2.1) update tb_rec set tb_rec.ds_status = 'L' ,tb_rec.baixado = getdate() ,tb_rec.id_Bordero = @id_Bordero from nc_receber tb_rec inner join tbl_Transacao_Forma tb_for on tb_rec.ChaveControle = tb_for.id_Chave_Controle where tb_for.id_Transacao_Pagar = @id_Transacao_Bordero Opção 2.2) update tb_rec set tb_rec.ds_status = 'L' ,tb_rec.baixado = getdate() ,tb_rec.id_Bordero = @id_Bordero from nc_receber where ChaveControle = (select id_Chave_Controle from tbl_Transacao_Forma where id_Transacao_Pagar = @id_Transacao)
Nei,
Complementando a informação do Junior, sua opção 2.1 é a melhor pela condição de processamento do comando UPDATE dentro do SQL Server.
Como referência, veja a documentação oficial do SQL Server para este comando (http://technet.microsoft.com/pt-br/library/ms177523.aspx#TableHints ) em especial à parte sobre Table Hint e o comando SELECT ( http://technet.microsoft.com/pt-br/library/ms189499.aspx ) onde à ordem de processamento lógico afeta a resolução e a performance da consulta, e consequentemente, afeta também os comandos DELETE e UPDATE da mesma forma. Segue abaixo a ordem de processamento lógico de uma instrução T-SQL:
1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. WITH CUBE OU WITH ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOPCom este conceito, podemos afirmar que é possível obter o resultado desejado de performance através de condições "ON" em detrimento do "WHERE". Em alguns casos o ganho de sua consulta pode ser significativo, mas para poucos registros pode ser insignificante.
Um modo que pode ajudar sua decisão para verificar exatamente qual comando UPDATE é mais vantajoso (de forma simples) utilize antes da instrução o comando:
SET STATISTICS TIME ON GO SET STATISTICS IO ON GO update tb_rec set tb_rec.ds_status = 'L' ,tb_rec.baixado = getdate() ,tb_rec.id_Bordero = @id_Bordero from nc_receber tb_rec inner join tbl_Transacao_Forma tb_for on tb_rec.ChaveControle = tb_for.id_Chave_Controle where tb_for.id_Transacao_Pagar = @id_Transacao_Bordero SET STATISTICS TIME OFF GO SET STATISTICS IO OFF GO
Espero que seja útil para você.
Abraços,
Durval RamosMicrosoft Partner | MTA - SQL Server 2012---------------------------------- Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"- Sugerido como Resposta Roberto F FonsecaModerator terça-feira, 24 de dezembro de 2013 20:02
- Marcado como Resposta Durval RamosModerator terça-feira, 8 de abril de 2014 18:10
-
Amigo, sem dúvidas a opção 1.
Na opção 2, em algum momento a sua consulta vai buscar todos os registo que satisfação a condição do INNER JOIN e só depois é que ele volta a fazer um novo filtro. Tudo isto quando na opção 1 ele já vai filtrando os registos à medida que entra em contacto com a tabela do INNER JOIN.
Cumprimentos
-
-
-
José
Desde já quero agradecer a atenção de todos neste assunto, que esta me ajudando em muito em outros aspectos, e sobre a sua dúvida segue abaixo ?
from nc_receber tb_rec inner join tbl_Transacao_Forma tb_for on tb_rec.ChaveControle = tb_for.id_Chave_Controle where tb_for.id_Transacao_Pagar = @id_Transacao_Bordero 1) tb_rec.ChaveControle - identificador único 2) tb_for.id_Chave_Controle - identificador que se repete mais de uma vez. 3) tb_for.id_Transacao_Pagar - identificador que se repete mais de uma vez.
-
Deleted
- Marcado como Resposta Durval RamosModerator terça-feira, 8 de abril de 2014 18:10