【问题标题】:is this query optimized?此查询是否优化?
【发布时间】:2026-01-18 01:10:01
【问题描述】:

我得到了优化数据库的任务,因为这个数据库响应慢。 这可能吗,如果我有大约 90k 条记录,如果我想选择大约 27k 条记录,响应时间是 15s? 我的查询有什么问题吗?或者这是关于索引的?

SET NOCOUNT ON;
SELECT workID AS pageID,
       projectName AS recProject,
       workType AS recType,
       workTitle AS recTitle,
       workDescription,
       workDate AS recDate,
       startTime,
       endTime,
       RTRIM(LTRIM(firstName + ' ' + lastName)) AS recName
FROM dbo.vTimesheets WITH (NOLOCK)
WHERE isActiveProject = 1
    AND workType = 1
    AND timeFor = 2
ORDER BY recdate DESC, pageID DESC;
SET NOCOUNT OFF;

此视图查询

SELECT dbo.tblTimesheet.workID,
       dbo.tblTimesheet.staffID,
       dbo.tblTimesheet.workDate,
       dbo.tblTimesheet.startTime,
       dbo.tblTimesheet.endTime,
       dbo.tblTimesheet.projectID,
       dbo.tblTimesheet.timeFor,
       dbo.tblTimesheet.workType,
       dbo.tblTimesheet.workTitle,
       dbo.tblTimesheet.workDescription,
       dbo.tblProject.projectName,
       dbo.tblProject.isDeleted AS isDeletedProject,
       dbo.tblProject.isActive AS isActiveProject,
       dbo.tblUser.firstName,
       dbo.tblUser.lastName,
       dbo.tblUser.isDeleted AS isDeletedStaff,
       dbo.tblUser.staffType
FROM dbo.tblTimesheet WITH (NOLOCK)
INNER JOIN dbo.tblUser WITH (NOLOCK) ON dbo.tblTimesheet.staffID = dbo.tblUser.userID
INNER JOIN dbo.tblProject WITH (NOLOCK) ON dbo.tblTimesheet.projectID = dbo.tblProject.projectID
WHERE (dbo.tblTimesheet.isDeleted = 0)

【问题讨论】:

  • 检查你的执行计划它使用的是什么类型的扫描?
  • 发布您的执行计划以及您的问题
  • 如果您不包含索引,我们如何知道您的索引是否正常?
  • 对不起,我是 sql server 的新手
  • 所以您正在查询一个视图,请也发布它的代码

标签: sql-server database optimization sql-server-2012


【解决方案1】:
ALTER TABLE dbo.tblTimesheet
    ADD workDescription2 AS CAST(workDescription AS VARCHAR(MAX)) 
GO

CREATE INDEX ix ON dbo.tblTimesheet (projectID, staffID, workDate DESC, workID DESC)
    INCLUDE (startTime, endTime, workType, workTitle, workDescription2, timeFor, isDeleted)
    WHERE isDeleted = 0 AND workType = 1 AND timeFor = 2
    --WITH (DROP_EXISTING=ON)

SELECT t.workID AS pageID,
       t.workDate AS recDate,
       t.startTime,
       t.endTime,
       t.workType AS recType,
       t.workTitle AS recTitle,
       t.workDescription2 AS workDescription,
       p.projectName AS recProject,
       RTRIM(LTRIM(u.firstName + ' ' + u.lastName)) AS recName
FROM dbo.tblTimesheet t --WITH (INDEX (ix))
JOIN dbo.tblUser u ON t.staffID = u.userID
JOIN dbo.tblProject p ON t.projectID = p.projectID
WHERE t.isDeleted = 0
    AND p.isActive = 1
    AND t.workType = 1
    AND t.timeFor = 2
ORDER BY t.workDate DESC, t.workID DESC

this is the new execution plan

但这比以前慢了

【讨论】:

  • workDescription 使其运行缓慢。如果我删除它运行得更快。
  • 如果我有超过 8000 个字符,是否可以使用该 varchar(max)
  • 是的,当然...还要检查分配单元 - IN_ROWLOB_DATA。在您的情况下主要问题LOB
  • 嘿,我的 PM 不想将其更改为 VARCHAR(MAX),他担心数据被截断。如果我想让该查询比以前运行得更快,我应该怎么做
【解决方案2】:
CREATE INDEX ix1 ON dbo.tblTimesheet (projectID, staffID, workID)
    INCLUDE (workType, timeFor, isDeleted)
    WHERE isDeleted = 0 AND workType = 1 AND timeFor = 2

IF OBJECT_ID('tempdb.dbo.#temp') IS NOT NULL
    DROP TABLE #temp

CREATE TABLE #temp (
    workID INT PRIMARY KEY,
    recProject VARCHAR(50),
    recName VARCHAR(150)
)

INSERT INTO #temp (workID, recProject, recName)
SELECT t.workID,
       p.projectName,
       RTRIM(LTRIM(u.firstName + ' ' + u.lastName)) AS recName
FROM dbo.tblTimesheet t WITH (INDEX (ix1))
JOIN dbo.tblUser u ON t.staffID = u.userID
JOIN dbo.tblProject p ON t.projectID = p.projectID
WHERE t.isDeleted = 0
    AND p.isActive = 1
    AND t.workType = 1
    AND t.timeFor = 2

SELECT t.workID AS pageID,
       t.workDate AS recDate,
       t.startTime,
       t.endTime,
       1 AS recType,
       t.workTitle AS recTitle,
       t.workDescription,
       tt.recProject,
       tt.recName
FROM dbo.tblTimesheet t
JOIN #temp tt ON t.workID = tt.workID
ORDER BY t.workDate DESC, t.workID DESC
--OPTION(RECOMPILE)

【讨论】:

  • 另一个想法...从非簇索引中快速选择,然后加入簇索引。
  • 那个workID是主键...是不是需要重新索引?
  • 删除 ix 和计算列...并尝试此解决方案。
  • 什么都没有改变先生...仍然相同的执行时间... workDescription 有很多字符 (399721).. 是问题吗?
  • 是的...我试图避免重复阅读PK,但没有结果:(