INDEX для повышения производительности для View, содержащего ROW_NUMBER OVER PARTITION - PullRequest
0 голосов
/ 10 декабря 2018

Я создал следующий вид в SQL Server.Он использует два набора ROW_NUMBER OVER PARTITION запросов в представлении, поскольку две ссылочные таблицы будут иметь несколько вхождений одного и того же ServerName в диапазоне RowInsertDateTime даты / времени, и меня интересует только самая новая строка каждого из них.Таблица.

Для возврата 471 строки требуется 4 секунды.Ни одна из таблиц не содержит индексов.Мне нужна помощь, чтобы понять, какие индексы я мог бы добавить для повышения производительности представления.Я проверил фактический план выполнения, и два сорта отвечают за 11% и 35% от общей стоимости запроса.

Определение вида:

CREATE VIEW ViewInSiteSuperTable 
AS
     SELECT 
         sales.ServerName,
         GETDATE() AS RowInsertDateTime,
         sales.daily_sales,
         basket.AvgBasketAmount,
         basket.AvgBasketQty,
         oos.OutOfStockCount,
         tph.transactions_per_hour,
         tph.total_transactions
     FROM
         dbo.InSiteEodSalesPerDayPerStore sales WITH (NOLOCK) 
     INNER JOIN 
         (SELECT 
              ServerName, 
              RowInsertDateTime,
              AvgBasketAmount,
              AvgBasketQty
          FROM 
              (SELECT   
                   ServerName,
                   RowInsertDateTime,
                   AvgBasketAmount,
                   AvgBasketQty,
                   ROW_NUMBER() OVER (PARTITION BY ServerName ORDER BY RowInsertDateTime DESC) rn
               FROM 
                   InSiteAvgBasketSize) q
           WHERE 
               rn = 1) basket ON basket.ServerName = sales.ServeRName
    INNER JOIN
        (SELECT 
             ServerName,
             RowInsertDateTime,
             transactions_per_hour,
             total_transactions
         FROM 
             (SELECT 
                  ServerName,
                  RowInsertDateTime,
                  transactions_per_hour,
                  total_transactions,
                  ROW_NUMBER() OVER (PARTITION BY ServerName ORDER BY RowInsertDateTime DESC) rn
              FROM 
                  InSiteTxPerHourPerDayTotals) q
         WHERE 
             rn = 1) tph ON tph.ServerName = sales.ServerName
    INNER JOIN 
        dbo.InSiteOutOfStocksAllStores oos WITH (NOLOCK) ON oos.ServerName = sales.ServerName 
    WHERE   
        sales.daily_sales_date =  DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) 

План выполнения

enter image description here

1 Ответ

0 голосов
/ 10 декабря 2018

Указаны следующие индексы для устранения 2 сот:

create index ix_ServerName_RowInsertDateTime on InSiteTxPerHourPerDayTotals
(ServerName asc, RowInsertDateTime desc) include(transactions_per_hour, total_transactions)

create index ix_ServerName_RowInsertDateTime on InSiteAvgBasketSize
(ServerName asc, RowInsertDateTime desc) include(AvgBasketAmount, AvgBasketQty)

Однако вы должны включить actual execution plan в свой вопрос, и не в виде рисунка, а с использованием Вставить план

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

В этом случае индексы не предназначены дляудалить scan, но удалить sort.В любом случае обе таблицы будут отсканированы, вы хотите перечислить все строки, чтобы вы не могли удалить scan, но вы хотите перечислить в каждой группе ServerName, это первая index key, и вы хотите упорядочить поRowInsertDateTime внутри каждой группы, так что это вторая index key.Эти два поля, при заказе, уже имеют то, что вы хотите: они находятся в порядке внутри группы s.

Другие поля included, так как они не должны быть в порядке, но без них индекс не равен covering для вашего запроса, т.е. сервер выполнит поиск в базовой таблице, чтобы получить их, потому что они присутствуют в предложении select.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...