Справка по оптимизации SQL-запросов - PullRequest
0 голосов
/ 07 июля 2011

У меня следующий запрос SQL

Declare @tempcalctbl Table
(
    ItemId varchar(50),
    ItemLocation varchar(50),
    ItemNo varchar(50),
    Width real,
    Unit varchar(50),
    date datetime
)

Insert Into @tempcalctbl 
     Select distinct SubId,ItemLocation,ItemNo,
       (ABS((Select width From @temptbl a Where ItemProcess ='P1'and a.ItemId = c.ItemId 
           and a.ItemNo = c.ItemNo and a.ItemLocation = c.ItemLocation)
       -(Select width From @temptbl b Where ItemProcess ='P2' and b.ItemId = c.ItemId 
           and b.ItemNo = c.ItemNo and b.ItemLocation = c.ItemLocation))) * 1000,
       Unit,date
From @temptbl c
Group by ItemId,ItemLocation,ItemNo,Unit,date

Мне было интересно, как оптимизировать этот запрос. Идея состоит в том, чтобы найти разную ширину (элемент p1 - элемент p2) между ItemProcess 'P1' и 'P2' в соответствии с тем же ItemID, тем же ItemNo и тем же ItemLocation. У меня около 75000, и потребовалось более 25 минут, чтобы получить разницу в ширине для всех ItemId.

Я пытался использовать Group by для расчета ширины, но он возвращал бы несколько строк вместо просто значения, которое затем возвращало бы ошибку. Кстати, я использую MS SQL Server 2008, а @tempcalctbl - это таблица, которую я объявил в процедуре хранения.

Ответы [ 2 ]

0 голосов
/ 07 июля 2011

Ответ Джона Петрака - лучший запрос для этого случая. Если скорость все еще приемлема, возможно, вы можете сохранить @temptbl во временной реальной таблице и создать связанный индекс для этих четырех столбцов.

0 голосов
/ 07 июля 2011

Помогает ли следующее:

INSERT  INTO @tempcalctbl
SELECT  P1.SubId ,
        P1.ItemLocation ,
        P1.ItemNo ,
        ABS(P1.Width - P2.Width) * 1000 AS Width ,
        P1.Unit ,
        P1.date
FROM    @temptbl AS P1
        INNER JOIN @temptbl AS P2 ON P1.ItemId = P2.ItemId
                                     AND P1.ItemNo = P2.ItemNo
                                     AND P1.ItemLocation = P2.ItemLocation
WHERE   P1.ItemProcess = 'P1'
        AND P2.ItemProcess = 'P2'

EDIT

Чтобы использовать индексы, вам нужно изменить переменную таблицы на временнуюТаблица

CREATE TABLE #temptbl
(
    ItemId varchar(50),
    ItemLocation varchar(50),
    ItemNo varchar(50),
    Width real,
    Unit varchar(50),
    date DATETIME,
    ItemProcess INT,
    SubId INT
)

CREATE NONCLUSTERED INDEX Index01 ON #temptbl
(
    ItemProcess ASC,
    ItemId ASC,
    ItemLocation ASC,
    ItemNo ASC
)
INCLUDE ( SubId,Width,Unit,date)
GO

Это должно немного ускорить вас.

...