创建临时表或UNION ALL的速度有多快?

时间:2013-06-17 07:26:38

标签: sql-server performance

我正在尝试更快地在MS SQL Server 2008 R2中进行一些查询,有两种方法:

1)通过创建临时表:

IF OBJECT_ID('tempdb..#Rec') IS NOT NULL
BEGIN
DROP TABLE #Rec
END

CREATE TABLE #Rec
(
    ID int NULL,
    DateBeg datetime NULL,
    DateEnd datetime NULL,
    Artist varchar(200) NULL,
    DescriptionFull text NULL,
    ActionPlaceID int NULL,
    ActionTypeID smallint NULL,
    Visible tinyint NULL,
    Created datetime NULL,
    DateList varchar(4000) NULL,
    DatesAsPeriod tinyint NULL,
    ShowReservLegend tinyint NULL,
    ProviderID int NULL
)

INSERT INTO #Rec
SELECT ID,
    DateBeg,
    DateEnd,
    Artist,
    DescriptionFull,
    ActionPlaceID,
    ActionTypeID,
    Visible,
    Created,
    DateList,
    DatesAsPeriod,
    ShowReservLegend,
    ProviderID
FROM [ConcertDev].[dbo].[T_Action]
WHERE DateBeg BETWEEN '2012-01-01' AND '2012-06-01'

INSERT INTO #Rec
SELECT ID,
    DateBeg,
    DateEnd,
    Artist,
    DescriptionFull,
    ActionPlaceID,
    ActionTypeID,
    Visible,
    Created,
    DateList,
    DatesAsPeriod,
    ShowReservLegend,
    ProviderID
FROM [ConcertDev].[dbo].[T_Action]
WHERE DateBeg BETWEEN '2013-01-01' AND '2013-06-01'

SELECT * FROM #Rec

2)使用UNION ALL:

SELECT ID,
    DateBeg,
    DateEnd,
    Artist,
    DescriptionFull,
    ActionPlaceID,
    ActionTypeID,
    Visible,
    Created,
    DateList,
    DatesAsPeriod,
    ShowReservLegend,
    ProviderID
FROM [ConcertDev].[dbo].[T_Action]
WHERE DateBeg BETWEEN '2012-01-01' AND '2012-06-01'

UNION ALL

SELECT ID,
    DateBeg,
    DateEnd,
    Artist,
    DescriptionFull,
    ActionPlaceID,
    ActionTypeID,
    Visible,
    Created,
    DateList,
    DatesAsPeriod,
    ShowReservLegend,
    ProviderID
FROM [ConcertDev].[dbo].[T_Action]
WHERE DateBeg BETWEEN '2013-01-01' AND '2013-06-01'

我预计UNION ALL会更快,但事实并非如此。它只用了1秒就快了。

记录数为6147。 通过使用临时表方法,执行时间为18秒。 通过使用UNION ALL方法,执行时间为17秒。

那么,这是加速查询的正确方法吗?

2 个答案:

答案 0 :(得分:1)

你也可以这样做:

SELECT ID,
DateBeg,
DateEnd,
Artist,
DescriptionFull,
ActionPlaceID,
ActionTypeID,
Visible,
Created,
DateList,
DatesAsPeriod,
ShowReservLegend,
ProviderID

into #Rec

FROM [ConcertDev].[dbo].[T_Action]
WHERE DateBeg BETWEEN '2012-01-01' AND '2012-06-01'
OR
DateBeg BETWEEN '2013-01-01' AND '2013-06-01' 

SELECT * FROM #Rec
DROP TABLE #Rec

答案 1 :(得分:0)

可能,只要你使用UNION ALL。默认情况下,UNION表示DISTINCT 这可能导致额外的分拣步骤同样昂贵 作为临时表。

但在性能方面,总有很多“依赖” 所以,如果你所描述的情景有一些偏差, 真正的答案可能会有所不同。

我能想到的临时表的一个优点是你可以对它们应用indexes。因此,在处理大量需要尽快恢复结果的数据时,这应该会有所帮助。