..
A primeira solução é usar JOIN na consulta diretamente, reescrita da seguinte forma
SELECIONE PC.LastName +''+ PC.FirstName [Nome do Cliente]
, SC.CustomerType
FROM Sales.Customer SC
LEFT OUTER JOIN YES Sales.Individual
ON = SC.CustomerID SI.CustomerID
PC Person.Contact LEFT OUTER JOIN
ON = SI.ContactID PC.ContactID
Nesta segunda versão eu simplesmente usei as tabelas no GetName função de colocá-los na cláusula FROM. Eu também substituiu o GetName chamada de função na lista de colunas na instrução SELECT concatenando diretamente as duas colunas à tabela Contact.
Aqui está o que o profiler mostra que executa esta consulta

Como você pode ver o rosto de inúmeras chamadas da versão anterior da consulta, a nova versão é uma única chamada que, naturalmente, significa uma grande economia em termos de desempenho.
Agora vamos ver o que acontece ao converter o GetName função original escalar em uma função que retorna uma tabela em vez (tabela inline). Primeiro, crie a função e denominiamola GetNameTable
CREATE FUNCTION GetNameTable (@ CustomerID int) Tabela retorna AS (RETURN SELECIONE LastName + ',' + Nome [Nome do Cliente] FROM Sales.Customer SC LEFT OUTER JOIN YES Sales.Individual ON = SC.CustomerID SI.CustomerID PC Person.Contact LEFT OUTER JOIN ON = SI.ContactID PC.ContactID ONDE CustomerID = @ SC.CustomerID )
Como você pode ver a consulta que extrai os dados é igual ao do GetName função escalar, a única diferença é que a função retorna um GetNameTable tabela em vez de um valor varchar. Para usar este novo recurso que ele usa é necessário usar o operador CROSS APPLY da seguinte forma
SELECIONE I. [Nome do Cliente]
, SC.CustomerType
FROM Sales.Customer SC
CROSS APPLY GetNameTable (SC.CustomerID) O
Neste caso, o resultado da seguinte Profiler

Vamos dar um exemplo final de como escrever a consulta original de forma mais eficiente. Desta vez, vamos criar e usar a seguinte visualização
CREATE VIEW View_GetName
AS
SELECIONE LastName + ',' + Nome [Nome do Cliente]
, SC.CustomerID
FROM Sales.Customer SC
JUNTE-SE AO Sales.Individual
ON = SC.CustomerID SI.CustomerID
JUNTE-SE PC Person.Contact
ON = SI.ContactID PC.ContactID
GO
A partir dessa visão, podemos escrever a nossa query da seguinte forma
V. SELECT [Nome do Cliente]
, CustomerType
FROM Sales.Customer SC
LEFT OUTER JOIN View_GetName V
ON SC.CustomerID CustomerID = R.
Neste caso, o resultado do Profiler é igual ao dos dois exemplos anteriores. Estes três exemplos são equivalentes, embora apresentando pequenas diferenças no desempenho. A abordagem mais eficiente é o CROSS JOIN resultando em um uso de CPU ligeiramente inferior (você pode ver a partir dos dados do Profiler).
Esses exemplos destinam-se a destacar que o uso de funções escalares na lista de colunas em uma instrução SELECT ou em uma cláusula WHERE é uma prática ineficiente. Os efeitos negativos desta prática é diretamente proporcional à quantidade de dados extraídos da consultas que são usadas. Quando usado desta forma, as funções escalares se comportar como um cursor que é chamado repetidamente, e em seguida pesar o desenvolvimento de nossas instruções. Se, portanto, usado em algumas de suas consultas consideradas funções escalares para reescrever o mesmo em uma das alternativas sugeridas.
Aqueles vistos neste artigo são apenas algumas das possíveis medidas para melhorar o desempenho do nosso T-SQL consultas e outros dispositivos úteis será discutido em artigos futuros.
| |
MS Curso de Acesso
Saiba como criar e gerenciar bancos de dados com facilidade e rapidez. -10% De desconto até 2012/06/01. |
| |
Curso de MySQL
Gestão de banco de dados open-source. -15% Desconto até 2012/06/01. |
| |
Banco de Dados e SQL Curso
Criar e gerenciar bancos de dados relacionais. -15% Desconto até 2012/06/01. |