Запросы на просмотры медленнее, чем выполнение одного запроса? - PullRequest
3 голосов
/ 11 июля 2010

Будет ли Mssql даже быстрее, когда я сделаю запрос к представлению, противоположному одному запросу?

пример

Когда у меня будет это представление:

create view ViewInvoicesWithCustomersName
Select * from Invoices left join Customer on Customer.ID=Invoices.CustomerID

Что будетбыстрее или будет еще быстрее?

a) select * from ViewInvoicesWithCustomersName where customerName="Bart"
b) select * from Invoices left join Customer on Customer.ID=Invoices.CustomerID
   where customername="Bart"

Ответы [ 5 ]

4 голосов
/ 11 июля 2010

Хотя в вашем простом примере все будет так же, необходимо соблюдать осторожность при использовании вложенных представлений.

Я работал в системе, в которой время ожидания запросов превышало 30 секунд, построенной на 6 уровнях вложенных представлений, и сумел ускорить их примерно в 100 раз, переписав запросы к базовым таблицам.

Ниже приведен простой пример типа проблемы, которая может возникнуть.

CREATE VIEW MaxTypes
AS
SELECT
  [number],
  MAX(type) AS MaxType
  FROM [master].[dbo].[spt_values]
GROUP BY [number]

GO

CREATE VIEW MinTypes
AS
SELECT
  [number],
  MIN(type) AS MinType
  FROM [master].[dbo].[spt_values]
GROUP BY [number]

GO
SET STATISTICS IO ON

SELECT     MaxTypes.number, MinTypes.MinType, MaxTypes.MaxType
FROM         MinTypes INNER JOIN
                      MaxTypes ON MinTypes.number = MaxTypes.number
ORDER BY MaxTypes.number

/*
Gives

Table 'spt_values'. Scan count 2, logical reads 16, physical reads 0, 
read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
*/
GO

SELECT 
  [number],
  MAX(type) AS MaxType,
  MIN(type) AS MinType
  FROM [master].[dbo].[spt_values]
GROUP BY [number]
ORDER BY  [number]

/*
Gives

Table 'spt_values'. Scan count 1, logical reads 8, physical reads 0, 
read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
*/

enter image description here

3 голосов
/ 11 июля 2010

Представление - это просто макрос, который развернут / не вложен в основной запрос.Таким образом, они эквивалентны.

Примечание: если имя клиента находится в таблице Customer, вы фактически создали INNER JOIN.Чтобы отфильтровать счета-фактуры Барта и без клиентов, вам необходимо сделать следующее:

select
  *
from
  Invoices
  left join
  Customer on Customer.ID=Invoices.CustomerID and customername="Bart"
2 голосов
/ 11 июля 2010

Оба должны занять почти одно и то же время.

Представление здесь - это просто представление запроса, который будет выполняться для данных при каждом обращении к представлению.

Существует другой тип представления, т.е. Материализованное представление . Этот тип представления имеет физическое существование в виде таблиц. И запрос (переданный во время создания представления) не выполняется при доступе к этому типу представления. выход из этого вида зрения должен быть быстрее.

2 голосов
/ 11 июля 2010

Они одинаковые, но просмотрите план выполнения, чтобы вы могли видеть, что происходит.Если у вас есть проблемы с производительностью, скорее всего, вам нужен индекс.Предполагая, что Customer.ID является первичным ключом с кластерным индексом, тогда Invoice.CustomerID и CustomerName являются хорошими кандидатами для индекса.

2 голосов
/ 11 июля 2010

Оба запроса будут эквивалентны.

...