如何提高 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 查询执行时间?的主要内容,如果未能解决你的问题,请参考以下文章