我想在我的数据库中的一堆表中进行基本的简单数据运行状况检查,以呈现给我的用户,所以我创建了这个:
SELECT
(SELECT COUNT(*) FROM StagingProducts
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0) AS NumProducts,
(SELECT COUNT(*) FROM StagingCategories
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0) AS NumCategories,
(SELECT COUNT(*) FROM ManufacturerSalesReps
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0) AS NumSalesReps,
(SELECT COUNT(*) FROM Orders
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0) AS NumOrders,
(SELECT COUNT(*) FROM StagingCustomers
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0) AS NumCustomers,
(SELECT COUNT(ItemID) As CategoryItemsCount FROM StagingCategoryItems
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0
AND ItemID NOT IN (SELECT ItemID FROM StagingProducts WHERE
ManufacturerID=@ManufacturerID AND IsDeleted=0)
) AS AbandonedCategoryItemsCount,
(SELECT COUNT(ChildItemID) As ChildCount FROM StagingChildItems
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0
AND ChildItemID NOT IN (SELECT ItemID FROM StagingProducts WHERE
ManufacturerID=@ManufacturerID AND IsDeleted=0)
) AS AbandonedChildCount,
(SELECT COUNT(RelatedItemID) As RelatedCount FROM StagingRelatedItems
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0
AND RelatedItemID NOT IN (SELECT ItemID FROM StagingProducts WHERE
ManufacturerID=@ManufacturerID AND IsDeleted=0)
) AS AbandonedRelatedCount,
(SELECT COUNT(TagID) As RelatedCount FROM StagingTags
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0
AND ItemID NOT IN (SELECT ItemID FROM StagingProducts WHERE
ManufacturerID=@ManufacturerID AND IsDeleted=0)
) AS AbandonedTagCount,
(SELECT COUNT(ItemID) As ModifierItemCount FROM StagingProductModifierLists
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0
AND ItemID NOT IN (SELECT ItemID FROM StagingProducts WHERE
ManufacturerID=@ManufacturerID)
) As AbandonedModifierItemCount,
(SELECT COUNT(*) FROM
(SELECT COUNT(*) AS CNT, CustomerNumber FROM StagingCustomers
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0
GROUP BY CustomerNumber HAVING COUNT(*) > 1
) AS DuplicateCustomerCount
) AS DuplicateCustomerCount,
(SELECT COUNT(*) FROM
(SELECT COUNT(*) AS CNT, ItemID FROM StagingProducts
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0
GROUP BY ItemID HAVING COUNT(*) > 1
) AS DuplicateItemCount
) AS DuplicateItemCount
这有时可以超快速运行,但在其他时候只是挂起服务器。对于我来说,将几个表中的数据转换为单个查询的最佳方法是什么?
答案 0 :(得分:1)
由于您在数据库中触摸了这么多表,并且在运行查询时可以使用这些表中的任何一个,如果从表中获取绝对最新信息并不是非常重要,我会使用
ALTER PROCEDURE [dbo].[WebManager_DataHealth] @ManufacturerID INT
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT .....
END
答案 1 :(得分:0)
作为识别问题的第一步,我建议将每个子查询分开并选择它们之间的当前日期和时间 - 如下所示:
select getdate()
SELECT COUNT(*) AS NumProducts FROM StagingProducts
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0
select getdate()
SELECT COUNT(*) AS NumCategories FROM StagingCategories
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0
...
这可以让您识别哪些是有问题的查询。 (如果这是由对数据库资源的同时需求太多引起的,可能会减少问题。)
作为第二步,我会考虑将NOT IN子查询重构为NOT EXISTS子查询 - 如下所示:
SELECT COUNT(ItemID) As CategoryItemsCount FROM StagingCategoryItems sci
WHERE ManufacturerID=@ManufacturerID AND IsDeleted=0 AND NOT EXISTS
(SELECT NULL FROM StagingProducts sp WHERE sp.ItemID = sci.ItemID and
ManufacturerID=@ManufacturerID AND IsDeleted=0)
虽然我发现这种类型的重构可以提高性能,但我强烈建议您检查NOT EXISTS和NOT IN表单的运行时间 - 情况可能会有所不同。
我还建议检查有问题(即长时间运行)查询的查询计划,检查相关表上的索引是否正确使用,以及新索引是否可以提高性能。