2013-02-11 2 views
3

У меня есть две таблицы, каждая из которых занимает около 500 тыс. Строк (и растет). Вставки/обновления происходят с ними постоянно, иногда 100 секунд в минуту. В системе возникают проблемы с производительностью, а именно тайм-ауты, на базовые вставки в эти таблицы. Мы настроили наши индексы и выполнили обычные оптимизации. Но мне интересно, может ли тот факт, что эти две таблицы ссылаться на 5 видов с тяжелым соединением, может быть вредным. Я всегда думал, может быть, ошибочно, что по мере изменения базовых таблиц тоже меняются взгляды, которые ссылаются на них. Поэтому, если таблицы сильно меняются, возможно, наша система становится переполненной необходимостью постоянно играть в догоняющие обновления.Когда обновляются SQL Server Views?

+0

Оба ответа точны. Представление, по существу, сокращает использование подзапроса в соединении. Существует ряд причин, по которым могут возникать ваши тайм-ауты; поскольку вы сказали, что тайм-аут, а не тупик, я предполагаю, что вставки вызывается из-за пределов SQL. Можете ли вы предоставить дополнительную информацию о том, как происходят таймауты? Возможно, у вас слишком низкий порог тайм-аута (например, с объектом SqlCommand). –

+1

Я довольно большой противник использования просмотров в сохраненном коде. Если вы можете использовать представление, вы также можете записать соединения вручную, а не использовать представление. Проблема с представлением заключается в том, что вы пытаетесь использовать одностановичное решение для сценариев, которые, скорее всего, не требуют полного решения. Имейте в виду, что SQL очень хорошо оптимизирует себя, и это делается на основе используемых таблиц и конкретных столбцов, используемых из каждой таблицы. Если ваше представление возвращает 6 столбцов, но вам нужно всего четыре, тогда ваш запрос по своей сути неэффективен из-за представления. –

+2

@ Love2Learn - не совсем так. Если вы выбираете только 4 столбца из представления, оптимизатор может использовать эту информацию и создавать план, который не сможет предоставить другие столбцы, если такой план является жизнеспособным. Как я уже сказал, они оптимизируются во всем запросе (с расширением представлений в нем). –

ответ

10

Если они не indexed views (вы не говоря уже о таких в вашем вопросе), они не «обновляется» вообще.

Нормальный вид похож на макрос в C - это просто удобная стенография, чтобы скрыть часть большего выражения. Они раскрываются в дереве синтаксиса любого утверждения, ссылающегося на них, и все дерево затем компилируется и оптимизируется - в точке использования.


Для индексированных представлений, вы бы во многом правы - взгляды сохраняются как часть той же самой транзакции, которая выполняет изменения в базовых таблицах. Однако правила для индексированных представлений были разработаны таким образом, что это действие обновления не должно обладать слишком большим штрафом (их можно поддерживать без повторного запроса всей базовой таблицы).

+0

Определенно не индексированные представления. Я буду искать в других местах проблемы, спасибо! –

2

просмотров SQLServer не кэшируются, поэтому каждый раз, когда вы запрашиваете вид запроса выполняется

4

Это зависит:

1) Если вид не индексируется, то вид расширяется

-- View definition 
CREATE VIEW Sales.v_SalesOrderDetail 
AS 
SELECT h.SalesOrderID, h.SalesOrderNumber, h.OrderDate, 
     d.SalesOrderDetailID, d.OrderQty, d.UnitPrice, d.LineTotal, 
     p.ProductID, p.Name AS ProductName, p.Color AS ProductColor 
FROM Sales.SalesOrderHeader h 
INNER JOIN Sales.SalesOrderDetail d ON h.SalesOrderID = d.SalesOrderID 
INNER JOIN Production.Product p ON d.ProductID = p.ProductID 
GO 

-- View usage 
SELECT v.SalesOrderDetailID, v.OrderQty, v.UnitPrice, v.ProductName 
FROM Sales.v_SalesOrderDetail v 
WHERE v.ProductColor='Red'; 
GO 

Если посмотреть на план выполнения (SSMS: Ctrl + M), enter image description here затем мы увидим, что вид (FROM Sales.v_SalesOrderDetail v) расширен и сервер запрашивает только две таблицы: Sales.SalesOrderDetail d и Production.Product p. Более того, мы можем видеть, как соединение между Sales.SalesOrderHeader h и Sales.SalesOrderDetail d удаляется, потому что:

  • оговорка SELECT (SELECT v.SalesOrderDetailID, v.OrderQty, v.UnitPrice, v.ProductName) не включает в себя столбцы из таблицы Sales.SalesOrderHeader,

  • между этим двумя столовыми есть ограничение внешнего ключа и

  • Это ограничение FK является надежным.

2) Если вид индексируется (это означает, что существует UNIQUE CLUSTERED INDEX определен на представлении) и издание SQL Server является предприятие, то вид может быть расширен или нет. Если издание <> предприятие, то индексированное представление расширяется.Мы можем заставить сервер для не расширяют в [индексированный] вида с помощью NOEXPAND намека:

-- View definition 
CREATE VIEW Sales.v_SalesOrderDetail2 
WITH SCHEMABINDING 
AS 
SELECT h.SalesOrderID, h.SalesOrderNumber, h.OrderDate, 
     d.SalesOrderDetailID, d.OrderQty, d.UnitPrice, d.LineTotal, 
     p.ProductID, p.Name AS ProductName, p.Color AS ProductColor 
FROM Sales.SalesOrderHeader h 
INNER JOIN Sales.SalesOrderDetail d ON h.SalesOrderID = d.SalesOrderID 
INNER JOIN Production.Product p ON d.ProductID = p.ProductID 
GO 

-- Defining the UNIQUE CLUSTERED INDEX 
CREATE UNIQUE CLUSTERED INDEX PK_v_SalesOrderDetail2 
ON Sales.v_SalesOrderDetail2 (SalesOrderDetailID); 
GO 

-- View usage 
SELECT v.SalesOrderDetailID, v.OrderQty, v.UnitPrice, v.ProductName 
FROM Sales.v_SalesOrderDetail2 v WITH (NOEXPAND) 
WHERE v.ProductColor='Red'; 
GO 

В этом случае, мы можем видеть, что план выполнения enter image description here включает оператор Clustered Index Scan PK_v_SalesOrderDetail2. Таким образом, он использует индекс, определенный на втором представлении.

Знайте: SQL Server bug indexed view + MERGE.

-1

Индексирование индексов является хорошим, но, возможно, стоит подумать о том, как часто и когда вы обновляете статистику по этим индексам. Кроме того, использование буферной таблицы для хранения вставок, которые затем могут быть вставлены в виде массовой операции каждые 5 или 10 минут или что-то подходящее для вашей системы, может помочь (установка этого на отдельный физический диск была бы хорошей идеей.) Это сделало бы выбирает намного быстрее 90% времени и не намного хуже, чем текущие 10% времени.

Смежные вопросы