不知道如何构建快速查询

时间:2011-09-13 08:32:48

标签: sql performance tsql

昨天我已经问了一个类似的问题。 (Question
但是在自定义查询之后 - 性能真的很差。

场合

表位(数量:800'000)

Id    Number Leafnode From To   VersionId
-- --------- -------- ---- ---- ---------
 1 100200300        0 NULL NULL        33
 2 100200301        1 NULL NULL        34
 3 100200302        1    5   10        34
 ...

表变量(计数:1'300'000)

Id Number PositionId
-- ------ ----------
 1     01          2
 2     01          3
 3     02          3
 4     03          3
 ....

表变量文本(计数:1'300'000)

Id Language       Text VariableId
-- -------- ---------- ----------
 1        1      Hello          1
 2        2      Hallo          1
 3        3      Salut          1
 4        1        Bye          2
 5        2     Tschau          2
 ...

<小时/> 我正在寻找一个表现良好的查询(查看,存储过程,用户功能)。从我的应用程序中,我想使用如下的查询:

SELECT Id, Number, Text, Variable
FROM <whatever>
WHERE Language = 2 AND Version = 34 AND Number IN (100200301, 100200305)

结果应该是:

Id     Number   Text Variable
--  --------- ------ --------
 2  100200301  Hallo      01
 3  100200305 Tschau      01
...

<小时/> 的更新 我上传了包含上述三个表的数据库备份。 (Backup
我使用以下查询从位置表中获取'number'和'id'。没有加入,没有其他东西。此查询大约需要8分钟。

WITH C AS 
(
    SELECT T.Id, CAST(Number AS int) AS Nr, Version
    FROM Position AS T
    WHERE Leafnode = 1

    UNION ALL

    SELECT T.Id, Nr + 1 AS Expr1, T.[Version]
    FROM dbo.Position AS T 
    INNER JOIN C ON C.Id = T.Id AND T.[To] > CAST(STUFF(Nr, 1, 6, '') AS int)
)

SELECT Id, Nr, [Version]
FROM C
WHERE Version = 34 AND Nr = '241521123'
OPTION (maxrecursion 0)

5 个答案:

答案 0 :(得分:1)

可以通过在右列上创建正确的索引(clustered / nonclustered / composite / ...)来提高查询性能。

您可以使用查询计划来确定应在哪个列上创建索引。

您搜索,排序和加入的列上的索引可以是索引的候选者。

答案 1 :(得分:0)

您可能希望在“语言,版本和数量”列上添加一些索引

答案 2 :(得分:0)

您可以使用SET STATISTICS PROFILE ON为查询启用性能统计信息。这将显示查询的每个部分以及需要多长时间才能让您了解减慢它的速度。

我怀疑你正在使用它的IN运算符。你能改成WHERE(编号= 100200301或编号= 100200305)

http://wraithnath.blogspot.com/2011/01/getting-performance-data-from-sql.html

答案 3 :(得分:0)

您应该使用optmizer(来自查询计划)检查表的顺序。我认为它应该像位置表驱动查询(它应该是外表)作为其filtring大部分数据。如果其他表驱动查询然后强制计划并将位置表作为外表。 还要检查查询使用的索引是否正确,如果不长时间更新,则更新表的统计信息。

答案 4 :(得分:0)

这可能会导致问题

INNER JOIN C ON C.Id = T.Id AND T.[To] > CAST(STUFF(Nr, 1, 6, '') AS int)

从数字中删除前6位数字不是SARGable,可能会导致一些问题。

有几种方法可以解决这个问题,但最方便的可能是创建index on a computed column,其中计算列为STUFF(Number, 1, 6, '')

这需要SQL Server 2005或更高版本(请注意!=