我需要重写下面的查询,以便尽可能高效。有关如何提高此查询性能的任何建议?我计划将列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))
答案 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