【发布时间】:2019-02-23 01:40:59
【问题描述】:
运行 Windows Server 2012、Hyper-V、SQL Server 2012 主动/被动故障转移集群,配备两个 8 处理器、60GB 节点、单实例、300 个数据库。此查询产生不一致的结果,运行时间在 10 到 30 秒之间。
DECLARE @OrgID BigInt = 780246
DECLARE @ActiveOnly Bit = 0
DECLARE @RestrictToOrgID Bit = 0;
WITH og (OrgID, GroupID) AS
(
SELECT ID, ID FROM Common.com.Organizations WHERE ISNULL(ParentID, 0) <> ID
UNION ALL
SELECT o.ID, og.GroupID FROM Common.com.Organizations o JOIN og ON og.OrgID = o.ParentID
)
SELECT e.*, v.Type AS VendorType, v.F1099, v.F1099Type, v.TaxID, v.TaxPercent,
v.ContactName, v.ContactPhone, v.ContactEMail, v.DistrictWide,
a.*
FROM og
JOIN books.Organizations bo ON bo.CommonID = og.OrgID
JOIN books.Organizations po ON po.CommonID = og.GroupID
JOIN books.Entities e ON e.OrgID = po.ID
JOIN Vendors v ON v.ID = e.ID
AND (e.OrgID = bo.ID OR v.DistrictWide = 1)
LEFT JOIN Addresses a ON a.ID = e.AddressID
WHERE bo.ID = @OrgID
AND (@ActiveOnly = 0 OR e.Active = 1)
AND (@RestrictToOrgID = 0 OR e.OrgID = @OrgID)
ORDER BY e.EntityName
将LEFT JOIN Addresses 替换为JOIN Addresses
JOIN Addresses a ON a.ID = e.AddressID
WHERE bo.ID = @OrgID
AND (@ActiveOnly = 0 OR e.Active = 1)
AND (@RestrictToOrgID = 0 OR e.OrgID = @OrgID)
ORDER BY e.EntityName
或将从Addresses中选择的列的长度减少到小于100字节
SELECT e.*, v.Type AS VendorType, v.F1099, v.F1099Type, v.TaxID, v.TaxPercent,
v.ContactName, v.ContactPhone, v.ContactEMail, v.DistrictWide,
a.Fax
将执行时间减少到大约 0.5 秒。
另外,使用SELECT DISTINCT并将books.Entities加入Vendors
SELECT DISTINCT e.*, v.Type AS VendorType, v.F1099, v.F1099Type, v.TaxID, v.TaxPercent,
v.ContactName, v.ContactPhone, v.ContactEMail, v.DistrictWide,
a.*
FROM og
JOIN books.Organizations bo ON bo.CommonID = og.OrgID
JOIN books.Organizations po ON po.CommonID = og.GroupID
JOIN Vendors v
JOIN books.Entities e ON v.ID = e.ID
ON e.OrgID = bo.ID OR (e.OrgID = po.ID AND v.DistrictWide = 1)
将时间减少到大约 0.75 秒。
总结
这些情况表明 SQL Server 实例中存在某种资源限制,导致这些不稳定的结果,我不知道如何诊断它。如果我将有问题的数据库复制到运行 SQL Server 2012 的笔记本电脑上,则不会出现问题。我可以继续更改 SQL 并希望获得最好的结果,但我更愿意找到更明确的解决方案。
欢迎提出任何建议。
2/27/18 更新
将从Addresses中选择的列的长度减少到小于100字节
SELECT e.*, v.Type AS VendorType, v.F1099, v.F1099Type, v.TaxID, v.TaxPercent,
v.ContactName, v.ContactPhone, v.ContactEMail, v.DistrictWide,
a.Fax
将聚集索引搜索替换为聚集索引扫描以检索 a.Fax 和哈希匹配以将此值加入结果。
Addresses表主键创建如下:
ALTER TABLE dbo.Addresses
ADD CONSTRAINT PK_Addresses PRIMARY KEY CLUSTERED (ID ASC)
WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF,
ONLINE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON)
ON PRIMARY
每天都会根据需要对该索引进行碎片整理和优化。
到目前为止,我找不到任何有用的信息来解释为什么聚簇索引搜索会为查询增加这么多时间。
【问题讨论】:
-
你看过执行计划是否有明显的问题?
-
是的,我曾多次使用执行计划。这个案例没有显示任何明显的东西。我目前正在查看原始版本和修改为只读
a.Fax之间的差异比较,但同样,没有什么明显的。有关如何分析计划的任何建议? -
我已经更新了这篇文章,包括对执行计划的分析。
标签: sql-server-2012 windows-server-2012-r2 hyper-v recursive-cte