我在SQL Server 2008中运行的查询遇到了一些性能问题。我有以下查询:
查询1:
SELECT GroupID, COUNT(*) AS TotalRows FROM Table1
INNER JOIN (
SELECT Column1 FROM Table2 WHERE GroupID = @GroupID
) AS Table2
ON Table2.Column1 = Table1.Column1
WHERE CONTAINS(Table1.*, @Word) GROUP BY GroupID
Table1包含大约500,000行。表2包含大约50,000个,但最终将包含数百万个。使用查询,我发现重写以下查询会将查询的执行时间缩短到1秒以内。
查询2:
SELECT GroupID FROM Table1
INNER JOIN (
SELECT Column1 FROM Table2 WHERE GroupID = @GroupID
) AS Table2 ON Table2.Column1 = Table1.Column1
WHERE CONTAINS(Table1.*, @Word)
我不明白这是一个简单的计数查询。如果我在表1上执行以下查询,则返回< 1秒:
查询3:
SELECT Count(*) FROM Table1
此查询返回大约500,000作为结果。
然而,上面提到的原始查询(查询1)仅返回50,000的计数并且执行需要3秒,即使简单地移除GROUP BY(查询2)也将执行时间减少到< 1秒。
我不相信这是一个索引问题,因为我已经在相应的列上有索引。任何帮助都将非常感激。
答案 0 :(得分:0)
执行简单的COUNT(*) FROM table
可以更有效地扫描聚簇索引,因为它不必关心任何过滤,加入,分组等。包含全文搜索谓词的查询神秘的子查询必须做更多的工作。计数并不是那里最昂贵的部分 - 我敢打赌,如果你把数字排除在外,它们仍然会相对缓慢,但是将这个数字留在中,例如:
SELECT GroupID FROM Table1
INNER JOIN (
SELECT Column1 FROM Table2 WHERE GroupID = @GroupID
) AS Table2 ON Table2.Column1 = Table1.Column1
WHERE CONTAINS(Table1.*, @Word)
GROUP BY GroupID;
查看provided actual execution plan *中的the free SQL Sentry Plan Explorer,我看到了这一点:
而且:
这让我相信你应该:
Inventory
和A001_Store_Inventory
的统计信息,以便优化程序可以获得更好的行数估算(这可能会带来更好的计划形状)。Inventory.ItemNumber
和A001_Store_Inventory.ItemNumber
是相同的数据类型,以避免隐式转换。(*)免责声明:我为SQL Sentry工作。
答案 1 :(得分:0)
您应该查看查询计划,以查看SQL Server正在执行哪些操作来检索您请求的数据。另外,我认为最好重写原始查询,如下所示:
SELECT
Table1.GroupID -- When you use JOINs, it's always better to specify Table (or Alias) names
,COUNT(Table1.GroupID) AS TotalRows
FROM
Table1
INNER JOIN
Table2 ON
(Table2.Column1 = Table1.Column1) AND
(Table2.GroupID = @GroupID)
WHERE
CONTAINS(Table1.*, @Word)
GROUP BY
Table1.GroupID
另外,请记住,简单的COUNT和带有JOIN和GROUP BY的COUNT不是一回事。在一种情况下,它只是通过索引并进行计数,另一种是涉及其他表和分组,这可能是耗时的,具体取决于几个因素。