Нужен совет.Следующие изменения заставляют мою хранимую процедуру ВЫПОЛНИТЬ на 5 минут - PullRequest
1 голос
/ 09 июля 2019

У меня есть следующий вид:

ALTER VIEW [dbo].[vAccount]
AS
with cte_accounts_data AS 
(
SELECT
         null as CompanyVendorAccountId
        ,CAST(0 as bit) as IsVendorAccount
        ,null as VendorAccountReference
        ,null as VendorCompanyId
        ,a.[AccountId]
        ,a.[CompanyId]
        ,a.[CompanyAccountTypeId]
        ,ag.[CompanyAccountGroupId]
        ,ag.[Name] as CompanyAccountGroupName
        ,a.[RegionId]
        ,a.[Name]
        ,CONCAT(c.ShortName + ': ', a.[Name], ' [' + a.[Code] +']') AS DisplayName
        ,a.[Code]
        ,a.[Address]
        ,a.[Email]
        ,a.[IncludeEscalationEmail]
        ,a.[GPSLat]
        ,a.[GPSLong]
        ,a.[Telephone]
        ,a.[VATNumber]
        ,a.[AutoReceive]
        ,a.[AutoIssue]
        ,a.[IsBillableToAccount]
        ,a.[BillingStart]
        ,a.[IsEquipmentDepot]
        ,a.[IsShiftAttendanceEnabled]
        ,a.[ShiftMinHoursForLunchDeduction]
        ,a.[NightShiftStart]
        ,a.[NightShiftEnd]
        ,a.[ShiftStartDayOfMonth]
        ,a.[OperatingHoursStart]
        ,a.[OperatingHoursEnd]
        ,a.[LoadBays]
        ,a.[LoadInterval]
        ,a.[ArrivalInterval]
        ,a.[OverrideStockTakeCloseBalanceTime]
        --,a.[RFEquipment]
        ,a.[temp_IgnoreVendorIssueViaSAP]
        ,a.[Archived]
        ,a.[CreatedDate]
        ,a.[CreatedBy_PersonId]
        ,a.[UpdatedDate]
        ,a.[UpdatedBy_PersonId]
        ,cat.Name as CompanyAccountTypeName
        ,at.Name as AccountTypeName
        ,at.AccountTypeId
        ,at.EnumAccountType
        ,r.Name as Region
        ,c.Name as Company
        ,CONCAT(c.Code, ': ', a.Name, ' ',a.Code, ' ', c.Name, ' ', r.Name, ' ', at.Name, ' ', r.Code, ' ') as ViewSearchColumn
    FROM
        [Account] a
    JOIN Company c on (a.CompanyId = c.CompanyId)
    JOIN CompanyAccountType cat on (a.CompanyAccountTypeId = cat.CompanyAccountTypeId)
    JOIN AccountType at on (cat.AccountTypeId = at.AccountTypeId)
    LEFT OUTER JOIN vCompanyAccountGroup ag on (a.CompanyAccountGroupId = ag.CompanyAccountGroupId)
    LEFT OUTER JOIN Region r on (a.RegionId = r.RegionId)

    UNION 

    SELECT
         cv.[CompanyVendorAccountId]
        ,CAST(1 as bit) as IsVendorAccount
        ,cv.[VendorAccountReference]
        ,a.[CompanyId] as VendorCompanyId
        ,a.[AccountId]
        ,cv.[CompanyId]
        ,cv.[CompanyAccountTypeId]
        ,ag.[CompanyAccountGroupId]
        ,ag.[Name] as CompanyAccountGroupName
        ,a.[RegionId]
        ,a.[Name]
        ,CONCAT(c.ShortName + ': ', a.[Name], ' [' + cv.[VendorAccountReference] +']') AS DisplayName
        ,cv.[VendorAccountReference] as [Code]
        ,a.[Address]
        ,a.[Email]
        ,a.[IncludeEscalationEmail]
        ,a.[GPSLat]
        ,a.[GPSLong]
        ,a.[Telephone]
        ,a.[VATNumber]
        ,a.[AutoReceive]
        ,a.[AutoIssue]
        ,a.[IsBillableToAccount]
        ,a.[BillingStart]
        ,a.[IsEquipmentDepot]
        ,a.[IsShiftAttendanceEnabled]
        ,a.[ShiftMinHoursForLunchDeduction]
        ,a.[NightShiftStart]
        ,a.[NightShiftEnd]
        ,a.[ShiftStartDayOfMonth]
        ,a.[OperatingHoursStart]
        ,a.[OperatingHoursEnd]
        ,a.[LoadBays]
        ,a.[LoadInterval]
        ,a.[ArrivalInterval]
        ,a.[OverrideStockTakeCloseBalanceTime]
        --,a.[RFEquipment]
        ,a.[temp_IgnoreVendorIssueViaSAP]
        ,cv.[Archived]
        ,cv.[CreatedDate]
        ,cv.[CreatedBy_PersonId]
        ,cv.[UpdatedDate]
        ,cv.[UpdatedBy_PersonId]
        ,cat.Name as CompanyAccountTypeName
        ,at.Name as AccountTypeName
        ,at.AccountTypeId
        ,at.EnumAccountType
        ,r.Name as Region
        ,c.Name as Company
        ,CONCAT(c.Code, ': ', a.Name, ' ',a.Code, ' ', c.Name, ' ', r.Name, ' ', at.Name, ' ', r.Code, ' ') as ViewSearchColumn
    FROM
        [CompanyVendorAccount] cv
    JOIN Company c on (cv.CompanyId = c.CompanyId)
    JOIN CompanyAccountType cat on (cv.CompanyAccountTypeId = cat.CompanyAccountTypeId)
    JOIN AccountType at on (cat.AccountTypeId = at.AccountTypeId)
    JOIN Account a on (cv.VendorAccountId = a.AccountId)
    LEFT OUTER JOIN Region r on (a.RegionId = r.RegionId)
    LEFT OUTER JOIN vCompanyAccountGroup ag on (cv.CompanyAccountGroupId = ag.CompanyAccountGroupId)
    WHERE
        cv.CompanyId != a.CompanyId
)
,cte_ranking_order as 
(
    SELECT ROW_NUMBER() over (ORDER BY AccountId, CompanyId) as rankNumber,* FROM cte_accounts_data
)
SELECT  [CompanyVendorAccountId] 
       ,IsVendorAccount
       ,[VendorAccountReference]
       ,[VendorCompanyId]
       ,[AccountId]
       ,[CompanyId]
       ,[CompanyAccountTypeId]
       ,[CompanyAccountGroupId]
       ,[CompanyAccountGroupName]
       ,[RegionId]
       ,[Name]
       ,[DisplayName]
       ,[Code]
       ,[Address]
       ,[Email]
       ,[IncludeEscalationEmail]
       ,[GPSLat]
       ,[GPSLong]
       ,[Telephone]
       ,[VATNumber]
       ,[AutoReceive]
       ,[AutoIssue]
       ,[IsBillableToAccount]
       ,[BillingStart]
       ,[IsEquipmentDepot]
       ,[IsShiftAttendanceEnabled]
       ,[ShiftMinHoursForLunchDeduction]
       ,[NightShiftStart]
       ,[NightShiftEnd]
       ,[ShiftStartDayOfMonth]
       ,[OperatingHoursStart]
       ,[OperatingHoursEnd]
       ,[LoadBays]
       ,[LoadInterval]
       ,[ArrivalInterval]
       ,[OverrideStockTakeCloseBalanceTime]
       ,[temp_IgnoreVendorIssueViaSAP]
       ,[Archived]
       ,[CreatedDate]
       ,[CreatedBy_PersonId]
       ,[UpdatedDate]
       ,[UpdatedBy_PersonId]
       ,[CompanyAccountTypeName]
       ,[AccountTypeName]
       ,[AccountTypeId]
       ,[EnumAccountType]
       ,[Region]
       ,[Company]
       ,[ViewSearchColumn]
    FROM cte_ranking_order where rankNumber = 1
GO

, который я изменил, чтобы выглядеть как выше.

Ниже приведен исходный вид:

    ALTER VIEW [dbo].[vAccount]
AS

with cte_accounts_data AS 
(
SELECT
         null as CompanyVendorAccountId
        ,CAST(0 as bit) as IsVendorAccount
        ,null as VendorAccountReference
        ,null as VendorCompanyId
        ,a.[AccountId]
        ,a.[CompanyId]
        ,a.[CompanyAccountTypeId]
        ,ag.[CompanyAccountGroupId]
        ,ag.[Name] as CompanyAccountGroupName
        ,a.[RegionId]
        ,a.[Name]
        ,CONCAT(c.ShortName + ': ', a.[Name], ' [' + a.[Code] +']') AS DisplayName
        ,a.[Code]
        ,a.[Address]
        ,a.[Email]
        ,a.[IncludeEscalationEmail]
        ,a.[GPSLat]
        ,a.[GPSLong]
        ,a.[Telephone]
        ,a.[VATNumber]
        ,a.[AutoReceive]
        ,a.[AutoIssue]
        ,a.[IsBillableToAccount]
        ,a.[BillingStart]
        ,a.[IsEquipmentDepot]
        ,a.[IsShiftAttendanceEnabled]
        ,a.[ShiftMinHoursForLunchDeduction]
        ,a.[NightShiftStart]
        ,a.[NightShiftEnd]
        ,a.[ShiftStartDayOfMonth]
        ,a.[OperatingHoursStart]
        ,a.[OperatingHoursEnd]
        ,a.[LoadBays]
        ,a.[LoadInterval]
        ,a.[ArrivalInterval]
        ,a.[OverrideStockTakeCloseBalanceTime]
        --,a.[RFEquipment]
        ,a.[temp_IgnoreVendorIssueViaSAP]
        ,a.[Archived]
        ,a.[CreatedDate]
        ,a.[CreatedBy_PersonId]
        ,a.[UpdatedDate]
        ,a.[UpdatedBy_PersonId]
        ,cat.Name as CompanyAccountTypeName
        ,at.Name as AccountTypeName
        ,at.AccountTypeId
        ,at.EnumAccountType
        ,r.Name as Region
        ,c.Name as Company
        ,CONCAT(c.Code, ': ', a.Name, ' ',a.Code, ' ', c.Name, ' ', r.Name, ' ', at.Name, ' ', r.Code, ' ') as ViewSearchColumn
    FROM
        [Account] a
    JOIN Company c on (a.CompanyId = c.CompanyId)
    JOIN CompanyAccountType cat on (a.CompanyAccountTypeId = cat.CompanyAccountTypeId)
    JOIN AccountType at on (cat.AccountTypeId = at.AccountTypeId)
    LEFT OUTER JOIN vCompanyAccountGroup ag on (a.CompanyAccountGroupId = ag.CompanyAccountGroupId)
    LEFT OUTER JOIN Region r on (a.RegionId = r.RegionId)

    UNION 

    SELECT
         cv.[CompanyVendorAccountId]
        ,CAST(1 as bit) as IsVendorAccount
        ,cv.[VendorAccountReference]
        ,a.[CompanyId] as VendorCompanyId
        ,a.[AccountId]
        ,cv.[CompanyId]
        ,cv.[CompanyAccountTypeId]
        ,ag.[CompanyAccountGroupId]
        ,ag.[Name] as CompanyAccountGroupName
        ,a.[RegionId]
        ,a.[Name]
        ,CONCAT(c.ShortName + ': ', a.[Name], ' [' + cv.[VendorAccountReference] +']') AS DisplayName
        ,cv.[VendorAccountReference] as [Code]
        ,a.[Address]
        ,a.[Email]
        ,a.[IncludeEscalationEmail]
        ,a.[GPSLat]
        ,a.[GPSLong]
        ,a.[Telephone]
        ,a.[VATNumber]
        ,a.[AutoReceive]
        ,a.[AutoIssue]
        ,a.[IsBillableToAccount]
        ,a.[BillingStart]
        ,a.[IsEquipmentDepot]
        ,a.[IsShiftAttendanceEnabled]
        ,a.[ShiftMinHoursForLunchDeduction]
        ,a.[NightShiftStart]
        ,a.[NightShiftEnd]
        ,a.[ShiftStartDayOfMonth]
        ,a.[OperatingHoursStart]
        ,a.[OperatingHoursEnd]
        ,a.[LoadBays]
        ,a.[LoadInterval]
        ,a.[ArrivalInterval]
        ,a.[OverrideStockTakeCloseBalanceTime]
        --,a.[RFEquipment]
        ,a.[temp_IgnoreVendorIssueViaSAP]
        ,cv.[Archived]
        ,cv.[CreatedDate]
        ,cv.[CreatedBy_PersonId]
        ,cv.[UpdatedDate]
        ,cv.[UpdatedBy_PersonId]
        ,cat.Name as CompanyAccountTypeName
        ,at.Name as AccountTypeName
        ,at.AccountTypeId
        ,at.EnumAccountType
        ,r.Name as Region
        ,c.Name as Company
        ,CONCAT(c.Code, ': ', a.Name, ' ',a.Code, ' ', c.Name, ' ', r.Name, ' ', at.Name, ' ', r.Code, ' ') as ViewSearchColumn
    FROM
        [CompanyVendorAccount] cv
    JOIN Company c on (cv.CompanyId = c.CompanyId)
    JOIN CompanyAccountType cat on (cv.CompanyAccountTypeId = cat.CompanyAccountTypeId)
    JOIN AccountType at on (cat.AccountTypeId = at.AccountTypeId)
    JOIN Account a on (cv.VendorAccountId = a.AccountId)
    LEFT OUTER JOIN Region r on (a.RegionId = r.RegionId)
    LEFT OUTER JOIN vCompanyAccountGroup ag on (cv.CompanyAccountGroupId = ag.CompanyAccountGroupId)
    WHERE
        cv.CompanyId != a.CompanyId

Единственное, что я добавил, был этот cte:

 ,cte_ranking_order as 
(
    SELECT ROW_NUMBER() over (PARTITION BY AccountId, CompanyID ORDER BY AccountId, CompanyId) as rankNumber,* FROM cte_accounts_data
)

Смысл этого состоял в том, чтобы выбрать только уникальные учетные записи.из исходного списка выберите lsits, задав ему ROW_NUMBER() и разделив данные с помощью over (PARTITION BY AccountId, CompanyID ORDER BY AccountId, CompanyId).

Когда хранимая процедура пытается объединить это представление с некоторыми другими представлениями, переданными в конкретном @AccountId,хранимая процедура выполняется в течение 5 минут.

Я действительно не уверен, что это могло вызвать?

1 Ответ

1 голос
/ 10 июля 2019

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

Вы исключили возможность прослушивания параметров SQL как виновника?У меня это случалось много раз, выполнение запроса в окне запроса происходит быстро, но процедура sp занимает вечность.Это может произойти, когда включается сниффинг параметров. Этого можно избежать, назначив переданные переменные новым переменным в SP, а затем ссылаясь на них.

Так, например:

CREATE PROCEDURE dbo.MyProcedureName(
    @AccountID INT
)
BEGIN

    -- Prevent parameter sniffing.
    DECLARE @MyAccountID INT = @AccountID;

    SELECT
        ...
    FROM dbo.MyView
    WHERE
        MyView.AccountID = @MyAccountID;

   ...

END

Просто мысль, но это случалось со мной раньше, и я бился головой о стену, пытаясь понять это.

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

Некоторые дополнительные чтения по этому вопросу, если интересно: https://www.red -gate.com / simple-talk / sql / t-sql-программирования / параметр-сниффинг /

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