SQL2000 до SQL2005. Запрос теперь намного медленнее - PullRequest
0 голосов
/ 24 августа 2009

Этот запрос раньше занимал 3 сек в SQL2000, сейчас он занимает около 70 сек. Обе базы данных дают одинаковые результаты. База данных 2005 года не работает в режиме совместимости.

В настоящее время мы перестраиваем запрос для выполнения в SQL2005 .. путем исключения и понимания логики.

Однако - кто-нибудь может увидеть что-то очевидное, что мы пропустили.

И / или есть какие-нибудь инструменты, которые могли бы здесь помочь?

Мы смотрели план выполнения ... и профилировщик. И мастер настройки индекса.

Профилировщик указывает на огромное количество запросов, запрашивающих те же результаты.

Я знаю, что это очень сложный вопрос для отладки без данных ... другая пара глаз всегда хороша, если есть что-то очевидное!

Приветствия

Dave

ALTER            PROCEDURE [dbo].[GetNodeList]
@ViewID int,
@UserID int = null
as

Select ProcessList.*, 
A.NDOC_DOC_ID, 
A.NDOC_Order,
A.OMNIBOOK_ID, 
A.Node_Order
from (
    (SELECT N.NOD_ID, 
    N.NOD_Name, 
    N.NOD_Procname, 
    N.NOD_Xpos, 
    N.NOD_Ypos, 
    N.NOD_Zpos,
    VN.VNOD_VIE_ID
    FROM Node N 
    INNER JOIN View_NODe VN 
    ON N.NOD_ID = VN.VNOD_NOD_ID
    Where VN.VNOD_VIE_ID = @ViewID) ProcessList
Left Join
 (
    SELECT N.NOD_ID, 
    N.NOD_Name, 
    N.NOD_Procname, 
    N.NOD_Xpos as NOD_Xpos, 
    N.NOD_Ypos as NOD_Ypos, 
    N.NOD_Zpos as NOD_Zpos, 
    VN.VNOD_VIE_ID, 
    ND.NDOC_DOC_ID as NDOC_DOC_ID, 
    ND.NDOC_Order as NDOC_Order,
    null as OMNIBOOK_ID, 
    null as Node_Order
    FROM Node N 
    INNER JOIN View_NODe VN 
    ON N.NOD_ID = VN.VNOD_NOD_ID
    LEFT JOIN NODe_DOCument ND 
    ON N.NOD_ID = ND.NDOC_NOD_ID
    WHERE VN.VNOD_VIE_ID=@ViewID
    and ND.NDOC_DOC_ID is not null

    and (@UserID is null 
        or exists (Select 1 
                from Document D 
                where Doc_ID = ND.NDOC_DOC_ID 
                and dbo.fn_UserCanSeeDoc(@UserID,D.Doc_ID)<>0
        )
    )

    UNION

    SELECT N.NOD_ID, 
    N.NOD_Name, 
    N.NOD_Procname, 
    N.NOD_Xpos, 
    N.NOD_Ypos, 
    N.NOD_Zpos, 
    VN.VNOD_VIE_ID, 
    null, 
    null,
    NOM.OMNIBOOK_ID, 
    NOM.Node_Order
    FROM Node N 
    INNER JOIN View_NODe VN 
    ON N.NOD_ID = VN.VNOD_NOD_ID
    LEFT JOIN NODe_OMNIBOOK NOM 
    ON N.NOD_ID = NOM.NODE_ID
    WHERE VN.VNOD_VIE_ID=@ViewID
    and NOM.OMNIBOOK_ID is not null
    and exists (select 1 from Omnibook_Doc where OmnibookID = NOM.OMNIBOOK_ID)
) A
--On ProcessList.NOD_ID = A.NOD_ID
ON ProcessList.NOD_Xpos = A.NOD_Xpos
And ProcessList.NOD_Ypos = A.NOD_Ypos
And ProcessList.NOD_Zpos = A.NOD_Zpos
And ProcessList.VNOD_VIE_ID = A.VNOD_VIE_ID
) 
ORDER BY 
ProcessList.NOD_Xpos,
ProcessList.NOD_Zpos,
ProcessList.NOD_Ypos,
Coalesce(A.NDOC_Order,A.Node_Order),
Coalesce(A.NDOC_DOC_ID,A.OMNIBOOK_ID)

Ответы [ 4 ]

2 голосов
/ 24 августа 2009

Я видел это раньше, когда статистика не поспевала за данными. В этом случае возможно, что SQL Server 2005 использует статистику иначе, чем SQL Server 2000. Попробуйте перестроить свою статистику для таблиц, используемых в запросе; так для каждой таблицы:

UPDATE STATISTICS <table> WITH FULLSCAN

Да, я бы добавил FULLSCAN, если вы не знаете свои данные достаточно хорошо, чтобы думать, что образец записей даст достаточно хорошие результаты. Это замедлит создание статистики, но сделает ее более точной.

1 голос
/ 24 августа 2009

Возможно ли, что ваша статистика не попадалась? в базе 2к5? Таким образом, у базы данных нет информации, необходимой для составления хорошего плана? В отличие от вашей старой базы данных, которая имеет хорошую статистику в таблице и может выбрать лучший план для данных?

0 голосов
/ 25 августа 2009

Колледж разработал решение ... о возвращении функции fn_UserCanSeeDoc в SQL.

Ниже показан старый закомментированный код функции, а затем новый встроенный SQL. Теперь код работает очень быстро (от 1 минуты до секунды)

Глядя на старый SQL, я удивляюсь, насколько хорошо SQL2000 хорошо справился с его запуском!

Приветствия

--and dbo.fn_UserCanSeeDoc(@UserID,D.Doc_ID)<>0

-- if exists(Select 1 from Omnibook where Omnibook_ID = @DocID) 
--      Begin
--          Set @ReturnVal =  1
--      End 
--  
--  else
--      Begin
--          if exists(
--              Select 1
--              from UserSecurityModule USM
--              Inner join DocSecurity DS
--              On USM.SecurityModuleID = DS.SecurityModuleID
--              where USM.UserID = @UserID
--              and DS.DocID = @DocID
--          )
--          
--              Set @ReturnVal =  1
--          
--          else
--                  
--              Set @ReturnVal = 0
--      End

AND D.Doc_ID IN (select DS.DocID from UserSecurityModule USM
                Inner join DocSecurity DS
                On USM.SecurityModuleID = DS.SecurityModuleID
                where USM.UserID = @UserID)
0 голосов
/ 24 августа 2009

Может ли быть проблема с «анализом параметров», то есть SQL Server кэширует план запроса, оптимизированный для параметров, предоставленных для первого выполнения? Microsoft technet имеет больше

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