在存储过程中,我需要将长INSERT的结果转换为临时表。WHERE子句对于处于SELECT DISTINCT中的所有表都是相同的。
简化为可读性,如下所示:
INSERT INTO #MyTemp
SELECT col1, col2, col3 FROM tab1 WHERE col1 in (SELECT DISTINCT myId FROM TabIds) UNION
SELECT col1, col2, col3 FROM tab2 WHERE col1 in (SELECT DISTINCT myId FROM TabIds) UNION
SELECT col1, col2, col3 FROM tab3 WHERE col1 in (SELECT DISTINCT myId FROM TabIds) UNION
.
.
.
SELECT col1, col2, col3 FROM tab20 WHERE col1 in (SELECT DISTINCT myId FROM TabIds) 虽然TabIds是一个小的临时表,通常有3-6条记录,但这似乎是非常不方便的。
有更好的方法吗?
总结我的问题:
我是否可以只做一次SELECT DISTINCT myId FROM TabIds,并将其分配给一种数组/列表/集(而不是另一个临时表),然后在WHERE子句中使用它,如果有这种方法,那么对于这样一个小的(3-6 recs)临时表来说真的重要吗?
发布于 2013-03-06 14:21:25
我忽略了您的要求(“不对另一个临时表”),因为我不认为这是有充分根据的。试着看看这个解决方案是否提供了更好的性能:
SELECT i = myId
INTO #x
FROM dbo.TabIds -- please always use schema prefix
GROUP BY myId;
CREATE UNIQUE CLUSTERED INDEX x ON #x(i);
INSERT INTO #MyTemp(col1, col2, col3)
SELECT col1, col2, col3
FROM
(
SELECT col1, col2, col3 FROM dbo.tab1 WHERE EXISTS -- likely better than IN
(SELECT 1 FROM #x WHERE i = tab1.col1)
UNION ALL
SELECT col1, col2, col3 FROM dbo.tab2 WHERE EXISTS
(SELECT 1 FROM #x WHERE i = tab2.col1)
UNION ALL
...
UNION ALL
SELECT col1, col2, col3 FROM dbo.tab20 WHERE EXISTS
(SELECT 1 FROM #x WHERE i = tab20.col1)
) AS x
GROUP BY col1, col2, col3; -- likely more efficient than `UNION` to remove dupes当然,如果在所有20个表中对col1进行索引,并且该索引包括col2和col3,这将是最好的。
我建议使用视图的原因并不是因为我认为它会使代码运行得更快。只需创建一个视图,为您生成此UNION,从而简化此代码(以及重复此单调UNION的任何其他代码)。这是为了方便,而不是为了性能--尽管我需要明确的是,使用视图并不会神奇地使事情变慢。有时我可以,但这是一个危险和不合逻辑的理由,以避免意见。
最后,我强烈地考虑正常化。为什么这20张不同的桌子一开始都可以放在一张桌子上?
CREATE TABLE dbo.Normal
(
SourceTableID INT,
col1 <data type>,
col2 <data type>,
col3 <data type>
);
-- indexes / constraints
INSERT dbo.Normal
SELECT 1, col1, col2, col3 FROM dbo.tab1
UNION ALL
SELECT 2, col1, col2, col3 FROM dbo.tab2
UNION ALL
...
UNION ALL
SELECT 20, col1, col2, col3 FROM dbo.tab20;现在,您的所有查询都可以简单地引用这个新表。如果您通常只查找其中的一个源(例如tab5),那么在SourceTableID上进行索引或分区将是有用的。
发布于 2013-03-04 21:25:38
从概念上讲,对于一次性和数据加载来说,您所做的一切都很好。不过,我希望这不是生产代码中更大的模式的一部分。
发布于 2013-03-04 21:33:10
您要寻找的是一个公共表表达式。
我的rusty有点生疏,但是使用CTE,您的查询可能会如下所示:
WITH TabIds_CTE AS (SELECT DISTINCT myId FROM TabIds)
INSERT INTO #MyTemp
SELECT col1, col2, col3 FROM tab1 WHERE col1 IN (SELECT * FROM TabIds_CTE)
UNION ALL ...https://stackoverflow.com/questions/15211358
复制相似问题