查询调优SQL Server 2008
我有一个视图名为vw_AllJobsWithRecruiter查询调优SQL Server 2008,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有一个视图名为vw_AllJobsWithRecruiter ALTER VIEW dbo.vw_AllJobsWithRecruiter AS SELECT TOP(SELECT COUNT(iJobID_PK) FROM dbo.tbUS_Jobs) iJobId_PK AS JobId, dbo.ufn_JobStatus(iJobId_PK) AS JobStatus, dbo.ufn_RecruiterCompanyName(iJ
ALTER VIEW dbo.vw_AllJobsWithRecruiter
AS
SELECT TOP(SELECT COUNT(iJobID_PK) FROM dbo.tbUS_Jobs)
iJobId_PK AS JobId,
dbo.ufn_JobStatus(iJobId_PK) AS JobStatus,
dbo.ufn_RecruiterCompanyName(iJobId_PK) AS CompanyName,
sOther AS OtherCompanyName
FROM dbo.tbUS_Jobs
WHERE bDraft = 0
ORDER BY dtPostedDate DESC
此视图仅包含3278行
如果我执行以下查询:
SELECT * FROM vw_AllJobsWithRecruiter
WHERE OtherCompanyName LIKE '%Microsoft INC%'
它的执行时间不到一秒钟
现在我的问题是:
如果我使用下面的查询查询:
SELECT * FROM vw_AllJobsWithRecruiter
WHERE CompanyName LIKE '%Microsoft INC%'
OR OtherCompanyName LIKE '%Microsoft INC%'
执行需要30秒,从前端开始抛出超时错误。
功能如下:
CREATE Function [dbo].[ufn_RecruiterCompanyName] (@JobId bigint)
RETURNS nvarchar(200)
AS
BEGIN
DECLARE @ResultVar nvarchar(200)
DECLARE @RecruiterId bigint
select @RecruiterId = iRecruiterId_FK from dbo.tbUS_Jobs with (Nolock)
where iJobId_PK = @JobId;
Select @ResultVar = sCompanyName from dbo.tbUS_RecruiterCompanyInfo with (Nolock)
where iRecruiterId_FK = dbo.ufn_GetParentRecruiterID(@RecruiterId)
return isnull(@ResultVar,'')
END
另一个功能
CREATE Function [dbo].[ufn_GetParentRecruiterID](@RecruiterId bigint)
returns bigint
as
begin
declare @ParentRecruiterId bigint
SELECT @ParentRecruiterId = iParentId FROM dbo.tbUS_Recruiter with (Nolock)
WHERE iRecruiterId_PK = @RecruiterId
IF(@ParentRecruiterId = 0)
SET @ParentRecruiterId = @RecruiterId
RETURN @ParentRecruiterId
end
我的问题是
为什么要花这么多时间来执行?
如何减少执行时间?
非常感谢您的关注。第一个查询仅对返回的行调用dbo.ufn\u招聘公司名称,它会过滤存储值。对于第二个查询,SQL Server需要为所有行调用ufn。根据功能的不同,这可能会导致延迟 在查询分析器中选中此项,并尝试避免第二次查询^^ 在查看自定义函数之后,我建议使用联接表重写该视图。在这样的函数中进行查找时,SQLServer会为它接触或传递的每一行调用它们。使用左连接允许服务器更快地使用索引和键,并且应该在不到一秒钟的时间内交付数据 如果没有所有自定义函数和所有表的定义,我无法为您提供该新视图的示例,但它看起来应该有点像这样:
SELECT
jobs.Jobid,
jobstatus.Jobstatus,
recruiter.Company
FROM jobs
LEFT JOIN jobstatus ON jobs.Jobid = jobstatus.Jobid
LEFT JOIN recruiter ON jobs.Recruiterid = recruiter.Recruiterid
问题在于嵌套函数调用 您在WHERE子句中调用ufn_招聘公司名称,尽管是间接的 这意味着,WHERE子句是non-,并且必须为每一行运行该函数 该函数还调用ufn_GetParentRecruiterID。由于这是在第一个函数中的WHERE子句中,而且也是不可搜索的,所以基本上是对表中的每行执行两次表扫描
将函数调用替换为联接,您将看到性能的巨大提升。dbo.tbUS_Jobs中TOPSELECT COUNTiJobID_PK子句的目的是什么?这很奇怪,可能没用。如果您需要有iJobID_PK不为null的行,则where子句更合适。如果不使用子句TOPSELECT COUNTiJobID_PK FROM dbo.tbUS_Jobs,我就不能在视图中使用order by。@Skrol29该顶部。。构造等于SELECT TOP 100%,并指示SQL Server按顺序进行操作。如果没有陀螺,它会忽略订购。哇,陀螺的使用是绝对可怕的!如果需要按顺序排序,请将其放入查询中,而不是视图定义中。您的方法也不能保证有效。@ARINDAM-我没有说它会对您的性能问题负责,尽管它当然会节省不必要的子查询。从概念上讲,这完全是错误的做法。是的,你是对的。dbo.ufn_招聘公司的名字花费了很多时间。@Arindam-你能发布这个函数的代码吗?或者,在使用内部联接或其他筛选器运行函数之前,是否可以对结果进行预筛选?我编辑了我的问题,并使用了ufn_RecruiterCompanyName函数。我确信该函数可以被一些表联接所取代。然后,SQL Server将以比查询更快的速度为您提供结果@JNK我也添加了这个函数。是的,这是主要问题。我正试图通过加入来做到这一点。谢谢。