Использование итоги на агрегатах для повышения производительности

dba.stackexchange https://dba.stackexchange.com/questions/3039

Вопрос

У меня есть две таблицы: детали и общие данные этих деталей.

Подробности (Медленное решение):

select 
    OrderId             =   r.OrderId                   
  , TotalQty            =   SUM(r.Quantity)
  , TotalGrossConsid    =   SUM(r.Price * r.Quantity)
from dbo.Order r
group by r.OrderId

Итого (Быстрое решение):

select 
    t.OrderId                           
  , t.TotalQty          
  , t.TotalGrossConsid  
  , t.IsValid
from dbo.OrderTotal t

Иногда итоги становятся недействительными (некоторая работа должна пересматривать изменения, но это задержки). Как вы понимаете, второй запрос быстрее, а количество допустимых итоги больше, чем неверные. Таким образом, я ищу комбинированный запрос, который возвращает допустимые итоги со второй таблицы (итоги) и возвращает динамически пересчитанные итоги, используя первый медленный запрос. Таким образом, моя цель будет достигнута: все итоги являются действительными, и время до реагирования быстрее, чем полное пересчете.

Вот моя попытка (Гибридный раствор):

with fast_static(OrderId, TotalQty, TotalGrossConsid, IsValid)
as
(
    select 
        t.OrderId                           
      , t.TotalQty          
      , t.TotalGrossConsid  
      , t.IsValid
    from dbo.OrderTotal t
)

, slow_dynamic(OrderId, TotalQty, TotalGrossConsid)
(
   select 
        OrderId             =   r.OrderId                   
      , TotalQty            =   SUM(r.Quantity)
      , TotalGrossConsid    =   SUM(r.Price * r.Quantity)
    from dbo.Order r
)
select
    OrderId, TotalQty, TotalGrossConsid
from fast_static 
where IsValid = 1  
union all
select
  OrderId, TotalQty, TotalGrossConsid 
from slow_dynamic s 
    --inner join fast_static ff
    --on ff.OrderId = s.OrderId 
where   --ff.Valid = 0 -- too slow!!!
    s.OrderId in (select OrderId from fast_static f where f.Valid = 0)

Я сравнил быстрое решение и гибридный, я получил от 32% до 68% (относительные затраты на запрос). Если вы видите комментарий к варианту, он равен от 1% до 99% (слишком плохо). Можно ли улучшить этот запрос?

ДОБАВЛЕН

@GBN:

Valid  =  case when i.OrderId is null then 1 else 0 end
...
dbo.OrderTotal t  left join dbo.InvalidOrders i

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

РЕШЕНИЕ

Индексированные взгляды - лучший выбор. Помните о SQL Server Edition (noexpand подсказка для не входных изданий) и будьте готовы к воссоздать некоторые объекты базы данных (SET ANSI_NULLS ON, SET QUOTED_IDENTIFIER ON) начать использовать индексированные представления на стороне клиента.

Это было полезно?

Решение

Я не могу понять, почему вы не можете агрегировать на лету и почему это так медленно. Является ли «действительная» идея обходной точки

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

  • Предложение 1:

Создать вычисленный столбец

ALTER TABLE dbo.Order ADD PriceXQuantity AS Price * Quantity PERSISTED

Добавьте индекс

CREATE INDEX IX_Totals ON dbo.Order (OrderID) INCLUDE Quantity, PriceXQuantity)

Посмотрите, что произойдет

  • Предложение 2:

Используйте индексированный вид

CREATE VIEW OrderTotals
WITH SCHEMABINDING
AS
select 
    OrderId             =   r.OrderId                   
  , TotalQty            =   SUM(r.Quantity)
  , TotalGrossConsid    =   SUM(r.Price * r.Quantity)
  , COUNT_BIG(*) AS Dummy
from dbo.Order r
group by r.OrderId
GO
CREATE UNIQUE CLUSTERED INDEX IXCU_OrderTotals ON OrderTotals (OrderId9
GO

Вы также можете использовать вычисленный столбец здесь

Другие советы

Если стоимость не будет слишком высокой, вы можете подумать о перемещении IsValid флаг в Detail Таблица и указать это? Это замедлит ваши транзакции, но улучшит производительность запроса как (предположительно) большие Detail Таблица будет доступна в одном большом range scan

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top