SQL Query重写帮助

时间:2009-12-28 23:28:49

标签: sql sql-server sql-server-2005 performance

我需要重写下面的查询,以便尽可能高效。有关如何提高此查询性能的任何建议?我计划将列t2_1和t2_2设置为不可为空并分配默认值,我主要是关于是否/如何修改连接以便我可以移动“WHERE ... IN ...”部分。是否可以使用INNER JOIN?

SELECT t1_1 FROM t1
LEFT JOIN #t2 
ON t1.t1_3 = t2.t2_3
WHERE ISNULL (t2.t2_1, 54) in (SELECT ParsedValue FROM tf_ToTable(@IDList1))
AND ISNULL (t2.t2_2, 97) IN (SELECT ParsedValue FROM tf_ToTable(@IDList2))

5 个答案:

答案 0 :(得分:1)

SELECT  t1_1
FROM    #t2 
JOIN    t1
ON      t1.t1_3 = t2.t2_3
WHERE   t2.t2_1 = @IDList1
        AND t2.t2_2 = @IDList2
UNION ALL
SELECT  t1_1
FROM    t1
WHERE   @IDList1 = 54
        AND @IDList2 = 97
        AND t1_3 NOT IN
        (
        SELECT  t2_3
        FROM    #t2
        )

答案 1 :(得分:0)

如果您使t1.t1_3不可为空,则可以使用内连接替换左连接。

答案 2 :(得分:0)

首先,如果您的@ IDList1和@ IDList2是逗号分隔的字符串,则此查询根本不起作用。如果它们是表变量,那么您需要从表变量中获取一个SELECT才能使IN工作。

此外,由于您在公共论坛上发布此问题,我希望更改表名和列名以保护无辜者。就命名惯例而言,t1_1,t1_2等的列名称非常可怕。

我认为我起初误解了这个问题。以下是两种可能的解决方案:

SELECT
     T1.t1_1
FROM
     T1
LEFT JOIN #t2 T2 ON
     T2.t2_3 = T1.t1_3
WHERE
     EXISTS
     (
          SELECT
               ParsedValue
          FROM
               tf_ToTable(@IDList1)
          WHERE
               ParsedValue = ISNULL(T2.t2_1, 54)
     ) AND
     EXISTS
     (
          SELECT
               ParsedValue
          FROM
               tf_ToTable(@IDList2)
          WHERE
               ParsedValue = ISNULL(T2.t2_2, 97)
     )

或者,如果它是在分隔字符串中查找值的特定情况:

SELECT
     T1.t1_1
FROM
     T1
LEFT JOIN #t2 T2 ON
     T2.t2_3 = T1.t1_3
WHERE
     ',' + @IDList1 + ',' LIKE '%,' + CAST(ISNULL(T2.t2_1, 54) AS VARCHAR) + ',%' AND
     ',' + @IDList2 + ',' LIKE '%,' + CAST(ISNULL(T2.t2_2, 97) AS VARCHAR) + ',%'

最后一个查询假定您使用逗号作为分隔符,并且字符串中没有空格。如果需要,可以使用REPLACE函数去除字符串中的空格。

答案 3 :(得分:0)

您必须使用Reporting Services才能提供类似的列表,这意味着它正在使用动态SQL为您完成。

如果您正在使t2_1和t2_2禁止NULL,那么它们唯一的时间是NULL将是因为LEFT JOIN。

另外,考虑t2_3是否唯一,以及t1_3是否是该表中的外键,以及t1_3是否允许NULL。但我猜这不会是这种情况,因为#t2是一个临时表。

如果你可以摆脱ISNULL语句,那将有所帮助。

当然,不要忘记索引,并考虑你的表有多大。这里涉及的因素很多。

答案 4 :(得分:0)

我正在考虑下面的查询并将t2_1和t2_2更改为默认值不可为空将会给我带来最佳性能,你们怎么想?这不会允许最佳利用指数吗?

SELECT t1_1 FROM t1
LEFT JOIN #t2 ON t1.t1_3 = t2.t2_3
INNER JOIN tf_ToTable(@IDList1) x_1 ON t2.t2_1 = x_1.ParsedValue 
INNER JOIN tf_ToTable(@IDList2) x_2 ON t2.t2_2 = x_2.ParsedValue