具有分页、性能和优化的动态 SQL 查询

Jam*_*gan 2 performance sql-server dynamic-sql azure-sql-database query-performance

我面前有一个有趣的问题。有一个数据库有大约 100 万个用户帐户,预计每年增长 1-200 万个。该数据库是强 TPT,但此特定查询和所涉及的表不涉及任何 TPT 内容。

当指定第二个数据点(即电子邮件地址和姓氏、公司等)时,sproc 和视图的当前设计需要大约 15 秒来执行 (x2)。该数据库是 SQL Azure P11,但它不是 DTU 绑定查询,升级到最高可用产品 (P15) 对结果没有影响。

下面是 sproc、视图和执行计划。在过去 24 小时内重建或重组了所有索引,并更新了所有统计信息。例如,在查看数据时,历史电子邮件地址 (1..N) 的概念目前正在使用 aCROSS APPLY来获取最新的,这可以防止索引视图,可以通过简单地连接历史电子邮件地址和持久化来解决它们在一个列中。

许多数据库在 nvarchar(4000-max) 列中使用 JSON,所有这些列都有一个公开值并启用索引的计算列。范式必须支持分页,我正在寻找有关如何优化它的反馈/建议。

在这一点上,更改表结构不是一个可行的选择,尽管我可以通过一点点操作看到前进的道路。有没有人对我应该首先看哪里有任何想法?我已经对未知的重新编译和优化进行了测试,以查看是否有任何影响,如果有,则可以忽略不计。

注意:一些业务逻辑(专有列名被删除或修改,sproc和view不能按原样执行,但在功能上与源相同。

执行计划视图

程序

CREATE PROCEDURE [dbo].[spGetUserDetailsDynamic] @JsonFilter NVARCHAR(MAX)
AS /* Page number*/
DECLARE @Page AS INT = JSON_VALUE(@JsonFilter, '$.requestPaging.page');
/* Number of records on the page*/
DECLARE @Size AS INT = JSON_VALUE(@JsonFilter, '$.requestPaging.size');

IF (@Page = -1)
    SET @Page = 1;

IF (@Size = -1)
    SET @Size = 32767;

/* Sort direction ASC or DESC*/
DECLARE @SortDirection AS VARCHAR(10) = JSON_VALUE(@JsonFilter, '$.requestSorting.direction');
/* Order By Column */
DECLARE @SortColumn AS VARCHAR(200) = JSON_QUERY(@JsonFilter, '$.requestSorting.keys');

SET @SortColumn = REPLACE(@SortColumn, '"', '');
SET @SortColumn = REPLACE(@SortColumn, '[', '');
SET @SortColumn = REPLACE(@SortColumn, ']', '');

/* Filters*/
DECLARE @RequestorApplicationIdFilterValue AS TINYINT
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.applicationIdValue');

DECLARE @CompanyAssignedKeyFilterValue AS NVARCHAR(200)
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.companyAssignedKeyValue');
DECLARE @CompanyAssignedKeyFilterOperation AS NVARCHAR(200)
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.companyAssignedKeyOperation');


DECLARE @EmailFilterValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.emailValue');
DECLARE @EmailFilterOperation AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.emailOperation');


DECLARE @LastNameFilterValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.lastNameValue');
DECLARE @LastNameFilterOperation AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.lastNameOperation');


DECLARE @FirstNameFilterValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.firstNameValue');
DECLARE @FirstNameFilterOperation AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.firstNameOperation');


DECLARE @PhoneNumberFilterValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.phoneNumberValue');
DECLARE @PhoneNumberFilterOperation AS NVARCHAR(200)
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.phoneNumberOperation');

DECLARE @StreetAddressFilterValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.streetAddressValue');
DECLARE @StreetAddressFilterOperation AS NVARCHAR(200)
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.streetAddressOperation');

DECLARE @CityFilterValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.cityValue');
DECLARE @CityFilterOperation AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.cityOperation');

DECLARE @RegionFilterValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.regionValue');
DECLARE @RegionFilterOperation AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.regionOperation');

DECLARE @PostalCodeFilterValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.postalCodeValue');
DECLARE @PostalCodeFilterOperation AS NVARCHAR(200)
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.postalCodeOperation');

DECLARE @CountryFilterValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.countryValue');


DECLARE @HasCompletedRegistrationFilterValue AS NVARCHAR(200)
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.completedRegistrationValue');
DECLARE @HasCompletedRegistrationBitValue AS BIT = NULL;

IF (@HasCompletedRegistrationFilterValue IS NOT NULL)
BEGIN
    IF (@HasCompletedRegistrationFilterValue = 'true')
        SET @HasCompletedRegistrationBitValue = 1;
    ELSE
        SET @HasCompletedRegistrationBitValue = 0;
END;


DECLARE @HasApplicationAccountsFilterValue AS NVARCHAR(200)
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.haveApplicationAccountsValue');

DECLARE @HasApplicationAccountsBitValue AS BIT = NULL;

IF (@HasApplicationAccountsFilterValue IS NOT NULL)
BEGIN
    IF (@HasApplicationAccountsFilterValue = 'true')
        SET @HasApplicationAccountsBitValue = 1;
    ELSE
        SET @HasApplicationAccountsBitValue = 0;
END;

DECLARE @HasProcessorAccountsFilterValue AS NVARCHAR(200)
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.haveProcessorAccountsValue');

DECLARE @HasProcessorAccountsBitValue AS BIT = NULL;

IF (@HasProcessorAccountsFilterValue IS NOT NULL)
BEGIN
    IF (@HasProcessorAccountsFilterValue = 'true')
        SET @HasProcessorAccountsBitValue = 1;
    ELSE
        SET @HasProcessorAccountsBitValue = 0;
END;


DECLARE @TargetApplicationIdFilterValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.userTypeValue');


DECLARE @CompanyPublicIdValue AS NVARCHAR(200) = JSON_VALUE(@JsonFilter, '$.requestFiltering.companyPublicIdValue');
DECLARE @CompanyUserIdValue INT = NULL;

IF (@CompanyPublicIdValue IS NOT NULL)
BEGIN
    SET @CompanyUserIdValue =
    (
        SELECT UserId
        FROM Application.Users
        WHERE UserPublicId = @CompanyPublicIdValue
    );
END;


DECLARE @AccountPublicIdFilterValue AS VARCHAR(32)
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.accountPublicIdValue');

DECLARE @AccountIdFilterValue AS INT = JSON_VALUE(@JsonFilter, '$.requestFiltering.accountIdValue');



-- User Public ID
DECLARE @UserPublicIdFilterValue AS VARCHAR(32) = JSON_VALUE(@JsonFilter, '$.requestFiltering.userPublicIdValue');
DECLARE @UserIdFilterValue AS INT = JSON_VALUE(@JsonFilter, '$.requestFiltering.userIdValue');
IF (@UserPublicIdFilterValue IS NOT NULL AND @UserIdFilterValue IS NULL)
    SET @UserIdFilterValue =
(
    SELECT UserId
    FROM Application.Users
    WHERE UserPublicId = @UserPublicIdFilterValue
)   ;

DECLARE @UserRegistrationProgressStateFilterValue AS VARCHAR(32)
    = JSON_VALUE(@JsonFilter, '$.requestFiltering.userRegistrationProgressStateValue');
DECLARE @UserRegistrationProgressStateValue AS NVARCHAR(200) = NULL;

IF (@UserRegistrationProgressStateFilterValue IS NOT NULL)
BEGIN
    IF (@UserRegistrationProgressStateFilterValue = '4')
        SET @UserRegistrationProgressStateValue = '1,2';
    ELSE
        SET @UserRegistrationProgressStateValue = @UserRegistrationProgressStateFilterValue;
END;
    
DECLARE @TotalRecordCount INT;

DECLARE @WHERE AS NVARCHAR(MAX) = '';
DECLARE @GROUPBY AS NVARCHAR(MAX) = '';


DECLARE @SQLViewCount AS NVARCHAR(MAX)
    = '
    SELECT  @_TotalRecordCount = SUM(S.Total)
          FROM    (
                  SELECT    1 AS Total
                  FROM      Application.vwUserDetails T ';

DECLARE @SQL AS NVARCHAR(MAX)
    = '
    SELECT [Application_UserInvitations_ApplicationId]
      ,[Application_UserInvitations_EmailAddress]
      ,[Application_UserInvitations_InvitationStatusTypeId]
      ,[Application_UserInvitations_InvitationKey]
      ,[Application_UserInvitations_CompanyUserId]
      ,[Application_UserInvitations_Created]
      ,[Application_UserInvitations_Expires]
      ,[Application_Users_UserPublicId]
      ,[Application_Users_UserId]
      ,[Application_Users_UserCompanyAssignedKey]
      ,[Application_Users_FirstName]
      ,[Application_Users_LastName]
      ,[Application_Users_Created]
      ,[Application_Users_CompanyUserId]
      ,[Application_Users_ApplicationId]
      ,[Application_UserEmailAddresses_VerifiedEmailAddress]
      ,[Application_UserEmailAddresses_UnverifiedEmailAddress]
      ,[Application_UserInvitationRegistrationInformation_UserCompanyAssignedKey]
      ,[Application_UserInvitationRegistrationInformation_FirstName]
      ,[Application_UserInvitationRegistrationInformation_LastName]
      ,[Application_Companies_Name]
      ,[Application_Companies_UserTitleSubscriptionKey]
      ,[Application_Companies_CompanyUserId]
      ,[Application_Companies_CompanyId]
      ,[Application_Users_EvaluatedEmailAddress]
      ,[Application_Users_EvaluatedFirstName]
      ,[Application_Users_EvaluatedLastName]
      ,[Application_Users_EvaluatedUserCompanyAssignedKey]
      ,[Application_UserProfiles_PrimaryPhoneNumber]
      ,[Application_UserProfiles_MobilePhoneNumber]
      ,[UserHasApplicationAccount]
      ,[UserHasFinancialProcessorAccount]
      ,[Application_RegisterDate]
      ,[Application_Registration_Progress]
      ,[Application_Evaluated_User_Registration_Progress_Step]
      ,[Application_EvaluatedPhoneNumberCountry]
  FROM [Application].[vwUserDetails] T ';


DECLARE @SQLOrderBy AS NVARCHAR(200)
    = '
        
    ORDER BY 
        ' + ' ' + @SortColumn + ' ' + @SortDirection
      + '
    OFFSET (@_Page-1)*@_Size ROWS
        FETCH NEXT @_Size ROWS ONLY
    ';



/* Based off of requesting application, build the where clause, first with application specific filters, followed by general.*/
IF (
       @RequestorApplicationIdFilterValue IS NULL
       OR @RequestorApplicationIdFilterValue NOT IN ( 1, 2, 3 )
   )
BEGIN
    THROW 60000, 'ApplicationIdFilterValue is null or out of range', 1;
END;



IF (@CountryFilterValue IS NOT NULL)
BEGIN
    SET @WHERE
        = @WHERE + 'AND Application_UserAccountAddressCountryCode IN (''' + CAST(@CountryFilterValue AS VARCHAR(100))
          + ''') ';
END;

IF (@TargetApplicationIdFilterValue IS NOT NULL)
BEGIN
    SET @WHERE
        = @WHERE + 'AND Application_UserInvitations_ApplicationId IN ('
          + CAST(@TargetApplicationIdFilterValue AS VARCHAR(100)) + ') ';
END;

IF (@CompanyUserIdValue IS NOT NULL)
BEGIN
    SET @WHERE
        = @WHERE + 'AND Application_UserInvitations_CompanyUserId IN (' + CAST(@CompanyUserIdValue AS VARCHAR(100)) + ') ';
END;

IF (@HasProcessorAccountsBitValue IS NOT NULL)
BEGIN
    SET @WHERE
        = @WHERE + 'AND UserHasFinancialProcessorAccount = ' + CAST(@HasProcessorAccountsBitValue AS VARCHAR(100))
          + ' ';
END;

IF (@HasApplicationAccountsBitValue IS NOT NULL)
BEGIN
    SET @WHERE = @WHERE + 'AND UserHasApplicationAccount = ' + CAST(@HasApplicationAccountsBitValue AS VARCHAR(100)) + ' ';
END;

IF (@UserRegistrationProgressStateValue IS NOT NULL)
BEGIN
    SET @WHERE = @WHERE + 'AND Application_Registration_Progress IN (' + @UserRegistrationProgressStateValue + ') ';
END;

/* Fuzzy Text Search */
IF (@EmailFilterValue IS NOT NULL AND @EmailFilterOperation IS NOT NULL)
BEGIN
    -- IsEqualTo
    IF (@EmailFilterOperation = 0)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedEmailAddress = ''' + @EmailFilterValue + ''')';
    -- StartsWith
    ELSE IF (@EmailFilterOperation = 2)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedEmailAddress LIKE ''' + @EmailFilterValue + '%'')';
    -- Contains
    ELSE IF (@EmailFilterOperation = 3)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedEmailAddress LIKE ''%' + @EmailFilterValue + '%'')';
    -- EndsWith
    ELSE IF (@EmailFilterOperation = 5)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedEmailAddress LIKE ''%' + @EmailFilterValue + ''')';
END;

IF (
       @CompanyAssignedKeyFilterValue IS NOT NULL
       AND @CompanyAssignedKeyFilterOperation IS NOT NULL
   )
BEGIN
    -- IsEqualTo
    IF (@CompanyAssignedKeyFilterOperation = 0)
        SET @WHERE
            = @WHERE + 'AND (Application_Users_EvaluatedUserCompanyAssignedKey = ''' + @CompanyAssignedKeyFilterValue
              + ''')';
    -- StartsWith
    ELSE IF (@CompanyAssignedKeyFilterOperation = 2)
        SET @WHERE
            = @WHERE + 'AND (Application_Users_EvaluatedUserCompanyAssignedKey LIKE ''' + @CompanyAssignedKeyFilterValue
              + '%'')';
    -- Contains
    ELSE IF (@CompanyAssignedKeyFilterOperation = 3)
        SET @WHERE
            = @WHERE + 'AND (Application_Users_EvaluatedUserCompanyAssignedKey LIKE ''%' + @CompanyAssignedKeyFilterValue
              + '%'')';
    -- EndsWith
    ELSE IF (@CompanyAssignedKeyFilterOperation = 5)
        SET @WHERE
            = @WHERE + 'AND (Application_Users_EvaluatedUserCompanyAssignedKey LIKE ''%' + @CompanyAssignedKeyFilterValue
              + ''')';
END;

IF (
       @FirstNameFilterValue IS NOT NULL
       AND @FirstNameFilterOperation IS NOT NULL
   )
BEGIN
    -- IsEqualTo
    IF (@FirstNameFilterOperation = 0)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedFirstName = ''' + @FirstNameFilterValue + ''')';
    -- StartsWith
    ELSE IF (@FirstNameFilterOperation = 2)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedFirstName LIKE ''' + @FirstNameFilterValue + '%'')';
    -- Contains
    ELSE IF (@FirstNameFilterOperation = 3)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedFirstName LIKE ''%' + @FirstNameFilterValue + '%'')';
    -- EndsWith
    ELSE IF (@FirstNameFilterOperation = 5)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedFirstName LIKE ''%' + @FirstNameFilterValue + ''')';
END;

IF (
       @LastNameFilterValue IS NOT NULL
       AND @LastNameFilterOperation IS NOT NULL
   )
BEGIN
    -- IsEqualTo
    IF (@LastNameFilterOperation = 0)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedLastName = ''' + @LastNameFilterValue + ''')';
    -- StartsWith
    ELSE IF (@LastNameFilterOperation = 2)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedLastName LIKE ''' + @LastNameFilterValue + '%'')';
    -- Contains
    ELSE IF (@LastNameFilterOperation = 3)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedLastName LIKE ''%' + @LastNameFilterValue + '%'')';
    -- EndsWith
    ELSE IF (@LastNameFilterOperation = 5)
        SET @WHERE = @WHERE + 'AND (Application_Users_EvaluatedLastName LIKE ''%' + @LastNameFilterValue + ''')';
END;

IF (@CityFilterValue IS NOT NULL AND @CityFilterOperation IS NOT NULL)
BEGIN
    -- IsEqualTo
    IF (@CityFilterOperation = 0)
        SET @WHERE = @WHERE + 'AND (Application_UserAccountAddresses_City = ''' + @CityFilterValue + ''')';
    -- StartsWith
    ELSE IF (@CityFilterOperation = 2)
        SET @WHERE = @WHERE + 'AND (Application_UserAccountAddresses_City LIKE ''' + @CityFilterValue + '%'')';
    -- Contains
    ELSE IF (@CityFilterOperation = 3)
        SET @WHERE = @WHERE + 'AND (Application_UserAccountAddresses_City LIKE ''%' + @CityFilterValue + '%'')';
    -- EndsWith
    ELSE IF (@CityFilterOperation = 5)
        SET @WHERE = @WHERE + 'AND (Application_UserAccountAddresses_City LIKE ''%' + @CityFilterValue + ''')';
END;

IF (@RegionFilterValue IS NOT NULL AND @RegionFilterOperation IS NOT NULL)
BEGIN
    -- IsEqualTo
    IF (@RegionFilterOperation = 0)
        SET @WHERE = @WHERE + 'AND (Application_UserAccountAddresses_Region = ''' + @RegionFilterValue + ''')';
    -- StartsWith
    ELSE IF (@RegionFilterOperation = 2)
        SET @WHERE = @WHERE + 'AND (Application_UserAccountAddresses_Region LIKE ''' + @RegionFilterValue + '%'')';
    -- Contains
    ELSE IF (@RegionFilterOperation = 3)
        SET @WHERE = @WHERE + 'AND (Application_UserAccountAddresses_Region LIKE ''%' + @RegionFilterValue + '%'')';
    -- EndsWith
    ELSE IF (@RegionFilterOperation = 5)
        SET @WHERE = @WHERE + 'AND (Application_UserAccountAddresses_Region LIKE ''%' + @RegionFilterValue + ''')';
END;

IF (
       @PostalCodeFilterValue IS NOT NULL
       AND @PostalCodeFilterOperation IS NOT NULL
   )
BEGIN
    -- IsEqualTo
    IF (@PostalCodeFilterOperation = 0)
        SET @WHERE = @WHERE + 'AND (Application_UserAccountAddresses_PostalCode = ''' + @PostalCodeFilterValue + ''')';
    -- StartsWith
    ELSE IF (@PostalCodeFilterOperation = 2)
        SET @WHERE
            = @WHERE + 'AND (Application_UserAccountAddresses_PostalCode LIKE ''' + @PostalCodeFilterValue + '%'')';
    -- Contains
    ELSE IF (@PostalCodeFilterOperation = 3)
        SET @WHERE
            = @WHERE + 'AND (Application_UserAccountAddresses_PostalCode LIKE ''%' + @PostalCodeFilterValue + '%'')';
    -- EndsWith
    ELSE IF (@PostalCodeFilterOperation = 5)
        SET @WHERE
            = @WHERE + 'AND (Application_UserAccountAddresses_PostalCode LIKE ''%' + @PostalCodeFilterValue + ''')';
END;

IF (
       @StreetAddressFilterValue IS NOT NULL
       AND @StreetAddressFilterOperation IS NOT NULL
   )
BEGIN
    -- IsEqualTo
    IF (@StreetAddressFilterOperation = 0)
        SET @WHERE
            = @WHERE + 'AND (Application_UserAccountAddresses_StreetAddress1 = ''' + @StreetAddressFilterValue
              + ''' OR Application_UserAccountAddresses_StreetAddress2 = ''' + @StreetAddressFilterValue
              + ''' OR Application_UserAccountAddresses_StreetAddress3 = ''' + @StreetAddressFilterValue + ''')';
    -- StartsWith
    ELSE IF (@StreetAddressFilterOperation = 2)
        SET @WHERE
            = @WHERE + 'AND (Application_UserAccountAddresses_StreetAddress1 LIKE ''' + @StreetAddressFilterValue
              + '%'' OR Application_UserAccountAddresses_StreetAddress2 LIKE ''' + @StreetAddressFilterValue
              + '%'' OR Application_UserAccountAddresses_StreetAddress3 LIKE ''' + @StreetAddressFilterValue + '%'')';
    -- Contains
    ELSE IF (@StreetAddressFilterOperation = 3)
        SET @WHERE
            = @WHERE + 'AND (Application_UserAccountAddresses_StreetAddress1 LIKE ''%' + @StreetAddressFilterValue
              + '%'' OR Application_UserAccountAddresses_StreetAddress2 LIKE ''%' + @StreetAddressFilterValue
              + '%'' OR Application_UserAccountAddresses_StreetAddress3 LIKE ''%' + @StreetAddressFilterValue + '%'')';
    -- EndsWith
    ELSE IF (@StreetAddressFilterOperation = 5)
        SET @WHERE
            = @WHERE + 'AND (Application_UserAccountAddresses_StreetAddress1 LIKE ''%' + @StreetAddressFilterValue
              + ''' OR Application_UserAccountAddresses_StreetAddress2 LIKE ''%' + @StreetAddressFilterValue
              + ''' OR Application_UserAccountAddresses_StreetAddress3 LIKE ''%' + @StreetAddressFilterValue + ''')';
END;

IF (
       @PhoneNumberFilterValue IS NOT NULL
       AND @PhoneNumberFilterOperation IS NOT NULL
   )
BEGIN
    -- IsEqualTo
    IF (@PhoneNumberFilterOperation = 0)
        SET @WHERE
            = @WHERE + 'AND (Application_UserProfiles_Profile_vPrimaryTelephone_Numeric = ''' + @PhoneNumberFilterValue
              + ''' OR Application_UserProfiles_Profile_vMobileTelephone_Numeric = ''' + @PhoneNumberFilterValue + ''')';
    -- StartsWith
    ELSE IF (@PhoneNumberFilterOperation = 2)
        SET @WHERE
            = @WHERE + 'AND (Application_UserProfiles_Profile_vPrimaryTelephone_Numeric LIKE ''' + @PhoneNumberFilterValue
              + ''' OR Application_UserProfiles_Profile_vMobileTelephone_Numeric LIKE ''' + @PhoneNumberFilterValue
              + '%'')';
    -- Contains
    ELSE IF (@PhoneNumberFilterOperation = 3)
        SET @WHERE
            = @WHERE + 'AND (Application_UserProfiles_Profile_vPrimaryTelephone_Numeric LIKE ''%'
              + @PhoneNumberFilterValue + '%'' OR Application_UserProfiles_Profile_vMobileTelephone_Numeric LIKE ''%'
              + @PhoneNumberFilterValue + '%'')';
    -- EndsWith
    ELSE IF (@PhoneNumberFilterOperation = 5)
        SET @WHERE
            = @WHERE + 'AND (Application_UserProfiles_Profile_vPrimaryTelephone_Numeric LIKE ''%'
              + @PhoneNumberFilterValue + ''' OR Application_UserProfiles_Profile_vMobileTelephone_Numeric LIKE ''%'
              + @PhoneNumberFilterValue + ''')';
END;


SET @GROUPBY
    = '[Application_UserInvitations_ApplicationId]
      ,[Application_UserInvitations

Dav*_*oft 6

两个简单的改进:

  1. 通过强制转换@CompanyPublicIdValue为与UserPublicId相同的类型来修复此查询。 @CompanyPublicIdValue是 an nvarchar(32),它的数据类型优先级高于列类型。所以比较需要对每一行进行转换。

    它很贵,不应该。

    SET @CompanyUserIdValue =
        (
            SELECT UserId
            FROM Application.Users
            WHERE UserPublicId = @CompanyPublicIdValue
        )
    
    Run Code Online (Sandbox Code Playgroud)
  2. 不是在一个查询中计算行数并在下一个查询中返回它们,而是将键值提取到第一个查询中的临时表/表变量中,并将其加入到第二个查询中。

然后努力改进标识要返回的键的查询。也许该查询可以直接访问基表或索引视图。然后最终查询将您现有的视图连接到键值的临时表。