由于filegroup'default'中的磁盘空间不足,因此无法分配数据库'tempdb'的新页面。通过将对象放在文件组中,将其他文件添加到文件组中或为FileGroup中的现有文件设置自动化来创建必要的空间。
执行具有近2.5亿条记录的某些语句的存储过程时,面临此错误。
即使我在tempdb中有大约650GB的空间,但面临此错误。想知道我可以在这方面做些什么
查询:
SELECT u.Id, u.place, u.name, u.lname, LOWER(ue.email) AS Email, MIN(dp.BirthTime) AS Time
FROM tableA u
JOIN tableB ue ON ue.id = u.id AND ue.Did = 0
JOIN tableC dp ON dp.Id = u.Id
JOIN tableB dpe ON dpe.Id = dp.Id
LEFT JOIN tableB idpe ON idpe.Email = dpe.Email
LEFT JOIN tableE idp ON idp.Id = idpe.Id
LEFT JOIN tableD pidp ON pidp.Id = idp.Id
JOIN tableD cp ON dp.Id = cp.Id
where ISNULL(cp.FName,'') = '' AND ISNULL(cp.LName,'') = '' AND ISNULL(cp.IsActive,0) = 0 AND ISNULL(dp.Isinactive,0) = 0
AND ISNULL(pidp.FName,'') = '' AND ISNULL(pidp.LName,'') = ''
AND ISNULL(pidp.Isactive,0) = 0 AND ISNULL(idp.IsInactive,0)
AND ISNULL(u.EHome, '') != ''
GROUP BY u.Id, u.Isactive, u.name, u.EServer, ue.Email
tempdb不是问题。
查询具有多个具有不可降低表达式的过滤器。所有连接都必须在可以过滤的任何Where子句数据之前处理。如果您的最终结果(过滤和分组)为2.5亿行,我希望在连接率较高的数十亿美元之后的结果。在发生过滤和分组之前,必须将该结果构成。
。尝试将此ISNULL(cp.FName,'') = ''
更改为此(cp.FName = '' OR cp.FName IS NULL)
,以及所有类似的表达式。这至少可以允许在加入之前进行一些过滤。
第二步是删除结果集中未使用的连接。您只在表U,UE&中返回数据。DP。将另一个内在连接到存在的条款
中EXISTS (SELECT 1 FROM tableB dpe WHERE dpe.Id = dp.Id)
这将使初始联接产品将最初的产品减少到更可管理的东西。
您的左连接将更加复杂,但如果不是结果集的一部分,也不应成为联接。我阅读了您的查询,说您想在缺少数据的情况下过滤结果。例如,fname仅在fname是一个空字符串,空值或没有匹配记录的情况下才返回。另一种说法是,您不想看到带有非零/非布兰克值的fname,lname,iSActive的记录。
AND NOT EXISTS ( SELECT 1 FROM tableD AS pidp where pidp.Id = idp.Id AND fname <> '' AND lname <> '' AND isactive = 0)
如果所有3个填充,此语句将排除它们。如果您只想在任何一个字段具有价值的情况下排除它们,请将AND
更改为已存在子句中的OR
。
尝试以下更改,我希望您会完全避免使用肿的tempdb。
我可以看到查询的一些问题,这会使其效率低下:
-
LEFT JOIN tableD pidp
-您剩下加入此表,然后在Where子句中应用过滤条件:ISNULL(pidp.FName,'') = ''AND ISNULL(pidp.LName,'') = '' AND ISNULL(pidp.Isactive,0) = 0
ISNULL([col name], '') != ''
-非常低效的构造,可确保将永远不会使用列上的任何索引(如果存在)。如果列是不是将过滤器条件移至联接并删除ISNULL
:
ON pidp.Id = idp.Id AND pidp.FName = ''
AND pidp.LName = '' AND pidp.Isactive = 0
这也适用于ISNULL(idp.IsInactive,0)
参数。
-
GROUP BY
语句要解决由弱的加入/不良查询设计引起的问题 - 这是一个非常糟糕的查询设计的迹象,很可能是过度临时表使用的唯一原因。
我会根据这些行重写查询(我没有在步骤1中包含建议,因为它们取决于您的特定表定义):
SELECT u.Id, u.place, u.name, u.lname, LOWER(ue.email) AS Email, MIN(dp.BirthTime) AS Time
FROM tableA u
JOIN tableB ue ON ue.id = u.id AND ue.Did = 0
WHERE ISNULL(u.EHome, '') != ''
AND u.Id IN(
SELECT dp.id
FROM tableC dp
JOIN tableB dpe ON dpe.Id = dp.Id
LEFT JOIN tableB idpe ON idpe.Email = dpe.Email
LEFT JOIN tableE idp ON idp.Id = idpe.Id
LEFT JOIN tableD pidp ON pidp.Id = idp.Id
JOIN tableD cp ON dp.Id = cp.Id
where ISNULL(cp.FName,'') = '' AND ISNULL(cp.LName,'') = '' AND ISNULL(cp.IsActive,0) = 0 AND ISNULL(dp.Isinactive,0) = 0
AND ISNULL(pidp.FName,'') = '' AND ISNULL(pidp.LName,'') = ''
AND ISNULL(pidp.Isactive,0) = 0 AND ISNULL(idp.IsInactive,0)
)