如何提高 SSMS 中的 SQL 查询执行时间?

Posted

技术标签:

【中文标题】如何提高 SSMS 中的 SQL 查询执行时间?【英文标题】:How to boost up SQL query execution time in SSMS? 【发布时间】:2016-01-04 07:43:15 【问题描述】:

我使用以下查询从数据库中获取记录。

SELECT
    [dbo].[CamelCase](ISNULL(B.City, '')),
    CONVERT(VARCHAR(250), ISNULL(B.Addr1, '') + '/' + ISNULL(B.Addr2, '') + '/' + ISNULL(B.Area, '') + '/' + ISNULL(B.City, '') + '/' + ISNULL(B.State, '')),
    ISNULL(B.YardName, ''),
    DATEADD(HH, 10, CONVERT(DATETIME, A.Date_From)),
    DATEADD(HH, 17, CONVERT(DATETIME, A.Date_To)),
    '',
    ISNULL(B.Zone, ''),
    '',
    '',
    ISNULL(B.ContactPerson, ''),
    B.Mobile,
    ISNULL(B.EMailId, ''),
    '',
    A.AucCode,
    [dbo].[CamelCase](B.State),
    B.Pincode,
    [dbo].[CamelCase](ISNULL(B.City, ''))
FROM dbo.TBL_Auction A
JOIN dbo.TBL_PLACE B ON A.Auc_Place_Fk_Id = B.Place_Pk_Id

TBL_Auction 表中的索引:

Index Name ------------------- + Column Name -------- + Index Type
PK__PASS_AUC__8BC43C38517CE882 |  Auc_Pk_Id           | CLUSTERED   
IX_PASS_Created_On             |  Created_On          | NONCLUSTERED
Unq_Pass_Auction               |  Auc_Code            | NONCLUSTERED
Unq_Pass_Auction               |  Auc_Place_Fk_Id     | NONCLUSTERED
FK_Pass_Place                  |  Auc_Place_Fk_Id     | NONCLUSTERED

TBL_Place 表中的索引:

Index Name ------------------  + Column Name------- +  Index Type
PK__PASS_PLA__4F8634950F7A1AFB | Place_Pk_Id        |  CLUSTERED
IX_PASS_PLACE_I                | Place_Area         |  NONCLUSTERED
IX_PASS_PLACE_I                | Place_City         |  NONCLUSTERED
IX_PASS_PLACE_I                | Place_State        |  NONCLUSTERED
IX_PASS_PLACE_I                | Place_Country      |  NONCLUSTERED
IX_PASS_PLACE_I                | Place_Pincode      |  NONCLUSTERED
IX_PASS_PLACE_IV               | Place_Shrt_Code    |  NONCLUSTERED

但上述查询需要无限时间才能返回结果。

我已经为我的连接表创建了所有必要的索引。即使在那之后,优化器也会选择索引扫描而不是索引搜索。您可以在我的问题中检查两个表的索引列表。如何强制优化器选择索引查找?

当我使用Select *而不是指定Select Column Names时,此时查询结果已经在1秒内返回。在 Select 查询中指定列名时会出现什么问题?

编辑:-

ALTER FUNCTION [dbo].[CamelCase]
(@Str varchar(8000))
RETURNS varchar(8000) AS
BEGIN
  DECLARE @Result varchar(2000)
  SET @Str = LOWER(@Str) + ' '
  SET @Result = ''
  WHILE 1=1
  BEGIN
    IF PATINDEX('% %',@Str) = 0 BREAK
    SET @Result = @Result + UPPER(Left(@Str,1))+
    SubString  (@Str,2,CharIndex(' ',@Str)-1)
    SET @Str = SubString(@Str,
      CharIndex(' ',@Str)+1,Len(@Str))
  END
  SET @Result = Left(@Result,Len(@Result))
  RETURN @Result
END 

【问题讨论】:

虽然这对你帮助不大,但如果select * 几乎在瞬间返回,那么也许你可以尝试select * 到一个临时表,然后从那里选择你想要的列。这是一个讨厌的解决方法,也不是一个很好的解释,但想给我两分钱。 我的猜测是您在选择列表中调用的函数正在影响您的执行。尝试选择列但不使用 CamelCase(每行 3 次)和其他功能 你需要发布dbo.CamelCase的定义 @aardila,我已经更新了我的 dbo.CamelCase 函数。 【参考方案1】:

如果通过 NULL,您的骆驼案例函数将进入无限循环,因为退出的唯一方法是 PATINDEX('% %',@Str)= 0,并且计算结果为未知。

你需要解决这个问题。

您可以使用RETURNS NULL ON NULL INPUT,但为了安全起见,我也会明确处理它。

ALTER FUNCTION [dbo].[CamelCase] 
               (@Str VARCHAR(8000))
RETURNS VARCHAR(8000)
WITH RETURNS NULL ON NULL INPUT, 
     SCHEMABINDING
AS
  BEGIN
      IF @Str IS NULL
        RETURN NULL;

        /*.... Rest of function*/

【讨论】:

@IdoGal - 是的。 上面的查询需要无限时间才能返回结果。 - 第一个问题应该是“标量 UDF 是否可能进入无限循环”,答案是“是”。当然,当 OP 使用 * 时,他们不会调用该函数。 @MartinSmith,我已经更改了一些其他 UDF 函数来更改 State 和 City 列的 CamelCase。查询输出很快。谢谢你指引我正确的方向。 @MartinSmith,根据您建议的更改,我更改了我的 CamelCase UDF 函数。像魅力一样工作。 @MartinSmith,在不更改 UDF 函数的情况下,我在查询中进行了修改。我错过了提及 IsNull for State 列。选择 [dbo].[CamelCase](IsNull(B.State, '')), [dbo].[CamelCase](ISNULL(B.City, ''))。查询完美。

以上是关于如何提高 SSMS 中的 SQL 查询执行时间?的主要内容,如果未能解决你的问题,请参考以下文章

在SSMS中超链接SQL Server查询结果中的值

SSMS 2008 加载项 - 执行查询

通过删除执行计划中的排序运算符来优化 SQL 查询

如何提高sql中的查询性能?

在 Azure Data Studio 和 SSMS 或 s-s-rS 中执行 SQL 查询时的不同行为

如何根据 T-SQL (SSMS 2017) 中的下一条记录 [Effective Date]-1 计算到期日期?