2017-01-30 6 views
0

Я унаследовал несколько источников данных, и мне поручили интеграцию и отчет. Ничего нового.Деградация и оптимизация производительности запросов SQL Server

Проблема заключается в том, что, хотя у меня есть рабочий интегрированный запрос (как вид), производительность ухудшается ежедневно (от 8 до 12 секунд).

Ниже приведена упрощенная версия схемы таблиц и рабочий запрос для получения списка билетов.

/* Table Schema */ 
CREATE TABLE [dbo].[KioskImport](
    [ImportID] [bigint] IDENTITY(1,1) NOT NULL, 
    [ImportDate] [datetime] NOT NULL, 
    [TICKET_NBR] [varchar](25) NULL, 
    [TTL_AMT] [decimal](18, 2) NOT NULL, 
    [GROUP_ID] [varchar](15) NULL, 
    [SALE_DT] [date] NULL, 
    [SALE_TMS] [time](0) NULL, 
    [BADGE_NO] [varchar](25) NULL 
) ON [PRIMARY] 

/* Working Query */ 
SELECT 
    [KioskImport].TICKET_NBR 
    ,[KioskImport].GROUP_ID 
    ,[KioskImport].TTL_AMT 
    ,CONVERT(datetime, [KioskImport].SALE_DT) + CONVERT(datetime, [KioskImport].SALE_TMS) AS [SALE_DATE] 
    ,[KioskImport].BADGE_NO 
FROM [KioskImport] 
INNER JOIN 
(
    SELECT MAX(ImportID) MaxID, MAX(ImportDate) MaxDate, TICKET_NBR 
    FROM [KioskImport] 
    GROUP BY TICKET_NBR 
) [MaxRevenueImport] 
ON [MaxRevenueImport].MaxID = [KioskImport].ImportID 
AND [MaxRevenueImport].MaxDate = [KioskImport].ImportDate 

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

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

SQL версии 2008 R2

+1

какая версия сервера sql вы используете? – Hogan

+0

Здесь также есть странная проблема ... вы принимаете максимальную дату и максимальный id и соединяете их обоих, но они независимы - вы уверены, что одна и та же запись содержит максимальную дату как max id - и если вы, то maxid должно быть все, что вам нужно, чтобы присоединиться, поскольку in является уникальным. – Hogan

+1

Есть ли у вас какие-либо индексы? – SqlZim

ответ

0

Как некоторые из других людей указали, следует отметить, что версия SQL используется. Тем не менее, это может быть лучше, чем CROSS APPLY. Попробуйте изменить запрос:

SELECT 
    [KioskImport].TICKET_NBR 
    ,[KioskImport].GROUP_ID 
    ,[KioskImport].TTL_AMT 
    ,CONVERT(datetime, [KioskImport].SALE_DT) + CONVERT(datetime, [KioskImport].SALE_TMS) AS [SALE_DATE] 
    ,[KioskImport].BADGE_NO 
FROM [KioskImport] kiOuter 
CROSS APPLY (
    SELECT 
     kiInner.TICKET_NBR 
    FROM [KioskImport] kiInner 
    GROUP BY 
     kiInner.TICKET_NBR 
    HAVING 
     MAX(kiInner.ImportID) = kiOuter.ImportID 
     AND MAX(kiInner.ImportDate) = kiOuter.ImportDate 
    ) kiInner 

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

+0

Двойной контроль производительности, и я завысил, это до 12 секунд в неделю, а не в день. Индексы появляются смежными и в хорошем состоянии. Это общий сервер, поэтому возможны другие рабочие нагрузки. – Will

0

Я уверен, что крест применяется медленнее. Мой вопрос для вас - когда у вас есть MAX (kiInner.ImportID), что такое MAX (kiInner.ImportDate) для этого ImportID, или когда вы получаете MAX (kiInner.ImportDate), что такое MAX (kiInner.ImportID) для этого ImportDate. Возможно, они не в одном ряду. Я предлагаю использовать CTE.

;WITH cte AS (SELECT TICKET_NBR 
       , ImportID 
       , ImportDate 
       , ROW_NUMBER() OVER(PARTITION BY TICKET_NBR    
        ORDER BY ImportDate DESC, ImportID DESC) AS Rownum 
      FROM KioskImport 
) 
SELECT [KioskImport].TICKET_NBR 
    ,[KioskImport].GROUP_ID 
    ,[KioskImport].TTL_AMT 
    ,CONVERT(datetime, [KioskImport].SALE_DT) + CONVERT(datetime, [KioskImport].SALE_TMS) AS [SALE_DATE] 
    ,[KioskImport].BADGE_NO 
FROM [KioskImport] k 
INNER JOIN cte cte 
    ON cte.ImportID = k.ImportID 
    AND cte.ImportDate = k.ImportDate 
    AND cte.Rownum = 1; 
+0

CROSS APPLY работает, но не демонстрирует никакой разницы ни положительно, ни отрицательно. – Will

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