【问题标题】:T-SQL query runs very slowlyT-SQL 查询运行非常缓慢
【发布时间】:2021-05-16 08:34:32
【问题描述】:

我有一个查询正在处理,我认为它异常长,所以我正在改变一些事情并尝试不同的事情来加快它。目前,返回少于 11k 条记录需要 3 到 4 分钟。

这是我的查询:

DECLARE @PtVistitOID TABLE (
    PatientVisitOID INT NOT NULL
)

INSERT INTO @PtVistitOID
    SELECT DISTINCT PatientVisitOID
    FROM smsdss.c_covid_ptvisitoid_tbl
    WHERE PatientVisitOID IS NOT NULL

SELECT 
    A.OBJECTID AS PatientVisit_OID,
    A.PATIENTACCOUNTID,
    A.PatientVisitExtension_OID
FROM
    [SC_server].[Soarian_Clin_Prd_1].DBO.HPatientVisit AS A
INNER JOIN 
    [SC_server].[Soarian_Clin_Prd_1].dbo.HExtendedPatientVisit AS B ON A.PatientVisitExtension_OID = B.objectid
INNER JOIN 
    @PtVistitOID AS C ON A.ObjectID = C.PatientVisitOID
--WHERE A.ObjectID IN (SELECT PatientVisitOID FROM @PtVistitOID);

当我查看估计的查询执行计划时,它说大约 95% 的时间用于将记录插入到表中 @PtVisitOID,这部分查询将尽可能快地运行,您可以单击执行,有 13,970 @PtVisitOID 中的行。所以剩下的 5% 来自查询的其余部分。整个查询又需要 3 到 4 分钟。

所有连接都在完全相同类型的列上,INT。

我可以相当快地从所有单独的表中选择记录,不到 5 秒。尤其是当我添加最后一个 INNER JOIN 或将其更改为 WHERE A.ObjectID IN (SELECT PatientVisitOID FROM @PtVisitOID) 时,查询时间会增加。

有什么想法吗?

【问题讨论】:

  • 请问@PtVistitOID 中有多少条记录
  • 我将编辑问题以反映此信息,13,970
  • 有些表来自链接服务器?您应该在某处尝试remote join 提示;目前所有远程记录都可能被读取到当前数据库并加入到这里。
  • @table 变量在旧版本的 SQL Server 上表现糟糕,因为它们总是被估计为包含 1 行。考虑改用 #temp 表,在插入到表之后但在 select 语句中使用之前可能使用 update statistics #PtVistitOID with fullscan
  • @MCP_infiltrator 我想大概就是这样。表变量和链接服务器相结合会导致速度变慢。

标签: sql sql-server sql-server-2014


【解决方案1】:

我已经调整了编写查询的方式,并且很高兴地注意到执行时间下降到 1 到 2 秒之间。我确实撤回了更少的记录,但这很好,因为其他不再回来的记录毫无用处。这本身并不是加速的原因,重组才是。

DECLARE @PtVistitOID TABLE (
    PatientVisitOID INT NOT NULL
)

INSERT INTO @PtVistitOID
SELECT DISTINCT PatientVisitOID
FROM smsdss.c_covid_ptvisitoid_tbl
WHERE PatientVisitOID IS NOT NULL

DECLARE @UserDefinedString TABLE (
    PatientVisit_OID INT,
    PatientAccountID INT,
    Covid_Indicator VARCHAR(1000)
)

INSERT INTO @UserDefinedString
SELECT A.OBJECTID AS PatientVisit_OID,
    A.PATIENTACCOUNTID,
    --A.PatientVisitExtension_OID,
    B.UserDefinedString20
FROM [SC_server].[Soarian_Clin_Prd_1].DBO.HPatientVisit AS A
INNER JOIN [SC_server].[Soarian_Clin_Prd_1].dbo.HExtendedPatientVisit AS B ON A.PatientVisitExtension_OID = B.objectid
WHERE A.PatientVisitExtension_OID IS NOT NULL
AND B.UserDefinedString20 IS NOT NULL
AND B.UserDefinedString20 != ''

SELECT A.PatientVisitOID,
B.PatientAccountID,
B.Covid_Indicator
FROM @PtVistitOID AS A
INNER JOIN @UserDefinedString AS B
ON A.PatientVisitOID = B.PatientVisit_OID

通过不混合本地和链接服务器表的建议,通过选择在本地@tables 内生成所有结果,实现了所需的加速。

【讨论】:

  • 您首先使用表变量的任何原因,您不能将两个查询放在派生的子查询中吗?
  • 我可以,但这运行速度与我可以单击执行一样快,所以何必呢?这写起来很快,也很容易理解
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多