当已选择的表已经排序时,优化联合所有订单

时间:2013-11-25 14:51:42

标签: sql sql-server sql-order-by union-all

我说有3个以上的表,每个表包含1000多万行,每个表都有如下相同的结构:

Table1:    ColName | Type
           --------------
              cDT  | DateTime2(7)
              cID  | int
              c3   | ...
            ...    | ...

在(cDT,cID)上有一个聚簇索引,使得每个单独的表已经由cDT物理排序。使用cID是因为我通常只想要包含某些cID的行。

从这些表格中,我想为按时间排序的应用程序(即cDT)创建一个“流”。目前通过以下方式完成:

SELECT t.cDT AS cDT, t.cID AS cID, t.c3 AS c3, t.cTAB as cTab
FROM
(
SELECT cDT AS cDT, cID AS cID, c3 AS c3, 'tab1' as cTAB FROM TABLE1
UNION ALL
SELECT cDT AS cDT, cID AS cID, c3 AS c3, 'tab2' as cTAB FROM TABLE2
UNION ALL
SELECT cDT AS cDT, cID AS cID, c3 AS c3, 'tab3' as cTAB FROM TABLE3
)
WHERE t.cID IN (SELECT ID FROM TABLEIDs)
ORDER BY t.cDT

看到我的表已经使用聚簇索引正确排序我试图找到提高此查询性能的方法。我尝试使用视图,但这不起作用(无法在视图上创建索引)。我也试过单独使用一个独特的cDT列并使用连接,但这很麻烦(也许有人可以使用连接提供合适的解决方案?)。

显而易见的答案就是将所有内容都放在一个表中。我不介意在飞行中这样做,但我不想静态地这样做。

有关如何优化union all查询的任何想法,其中传入的表都是单独排序的,并且您想要进行全局排序?

先谢谢。

P.S。优化where语句并不重要,所以任何忽略我的where语句的解决方案仍然会非常感激。

查询计划:

enter image description here

1 个答案:

答案 0 :(得分:1)

SQL Server生成的计划似乎不太好。最好将三个表合并到一起加入到一个表中。也许我们可以欺骗SQL Server:

SELECT t.cDT AS cDT, t.cID AS cID, t.c3 AS c3, t.cTAB as cTab
FROM
(
SELECT TOP 1000000000 *
FROM (
 SELECT cDT AS cDT, cID AS cID, c3 AS c3, 'tab1' as cTAB FROM TABLE1
 UNION ALL
 SELECT cDT AS cDT, cID AS cID, c3 AS c3, 'tab2' as cTAB FROM TABLE2
 UNION ALL
 SELECT cDT AS cDT, cID AS cID, c3 AS c3, 'tab3' as cTAB FROM TABLE3
) x
ORDER BY cDT,cID --CI order
)
WHERE t.cID IN (SELECT ID FROM TABLEIDs)
ORDER BY t.cDT

这个几乎无限制的TOP子句可能会导致它在进行连接之前评估联合。 order-by应该有助于维护基表的CI顺序,以便不需要排序操作。

如果这不能立即起作用,请稍微尝试一下。