1

我正在尝试更快地在 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 秒。

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

4

2 回答 2

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
于 2013-06-17T10:23:38.067 回答
0

可能,前提是您使用 UNION ALL。默认情况下,UNION 意味着 DISTINCT,这可能会导致额外的排序步骤,这可能与临时表一样昂贵。

但是在性能方面总是有很多“取决于”,所以如果与您描述的场景有一些偏差,那么真正的答案可能会有所不同。

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

于 2013-06-17T07:32:42.137 回答