Sql server SQL Server中的表变量

Sql server SQL Server中的表变量,sql-server,Sql Server,我正在使用SQLServer2005。我听说我们可以使用一个表变量来代替左外连接 我的理解是,我们必须首先将左表中的所有值放到表变量中。然后我们必须用正确的表值更新表变量。然后从表变量中选择 有人遇到过这种方法吗?你能推荐一个带有查询的实时示例吗 我没有对此写任何疑问。我的问题是——如果有人使用过类似的方法,我想知道场景以及如何处理。我知道在某些情况下,它可能比左外连接慢 请假设我们处理的表的记录少于5000条 谢谢我认为从你的问题中不太清楚你想要实现什么?您的表是什么样子的,以及您想要什么结果

我正在使用SQLServer2005。我听说我们可以使用一个表变量来代替左外连接

我的理解是,我们必须首先将左表中的所有值放到表变量中。然后我们必须用正确的表值更新表变量。然后从表变量中选择

有人遇到过这种方法吗?你能推荐一个带有查询的实时示例吗

我没有对此写任何疑问。我的问题是——如果有人使用过类似的方法,我想知道场景以及如何处理。我知道在某些情况下,它可能比左外连接慢

请假设我们处理的表的记录少于5000条


谢谢

我认为从你的问题中不太清楚你想要实现什么?您的表是什么样子的,以及您想要什么结果。但您当然可以将数据选择到表数据类型的变量中,并对其进行篡改。非常方便:

DECLARE @tbl TABLE (id INT IDENTITY(1,1), userId int, foreignId int)

INSERT INTO @tbl (userId)
    SELECT id FROM users
    WHERE name LIKE 'a%'

UPDATE @tbl t
SET
    foreignId = (SELECT id FROM foreignTable f WHERE f.userId = t.userId)

在那个例子中,我给了表变量一个自己的标识列,与源表中的标识列不同。我经常觉得这很有用。随你的喜好调整。。。同样,问题是什么还不是很清楚,但我希望这可能会引导您走向正确的方向……?

每个场景都是不同的,如果没有具体案例的详细信息,很难说这是否是一个适合您的好方法

话虽如此,我不会考虑使用表变量方法,除非我有一个特定的功能原因——如果查询可以通过使用外部联接的标准SELECT查询来实现,那么我会使用它,因为我希望这是最有效的

您可能希望使用temp table/table变量来代替它的次数更多的是,您希望获得一个中间结果集,然后在返回它之前对它进行一些处理,即,这种处理不能用直接查询完成

请注意,表变量非常方便,但考虑到它们不能保证驻留在内存中-它们可以像标准临时表一样持久化到tempdb。

这是可以做到的,但我不知道您为什么要这么做

这真的看起来像是在倒退。但是,如果你只是为了自己的学习而尝试,那么以下是:

DECLARE @MainTable TABLE(
        ID INT,
        Val FLOAT
)

INSERT INTO @MainTable SELECT 1, 1
INSERT INTO @MainTable SELECT 2, 2
INSERT INTO @MainTable SELECT 3, 3
INSERT INTO @MainTable SELECT 4, 4

DECLARE @LeftTable TABLE(
        ID INT,
        MainID INT,
        Val FLOAT
)

INSERT INTO @LeftTable SELECT 1, 1, 11
INSERT INTO @LeftTable SELECT 3, 3, 33

SELECT  *,
        mt.Val + ISNULL(lt.Val, 0)
FROM    @MainTable mt LEFT JOIN
        @LeftTable lt ON mt.ID = lt.MainID

DECLARE @Table TABLE(
        ID INT,
        Val FLOAT
)

INSERT INTO @Table
SELECT  ID,
        Val
FROM    @MainTable

UPDATE  @Table
SET     Val = t.Val + lt.Val
FROM    @Table t INNER JOIN
        @LeftTable lt ON t.ID = lt.ID

SELECT *
FROM    @Table
谢谢你,阿斯坦德

我尝试了下面给出的一个例子。两种方法都用了19秒。然而,我想一些调整将有助于表变量更新方法比LEFT JOIN更快

由于我不是调谐方面的大师,我请求您的帮助。有SQL专家准备好证明这一点了吗

--请替换为以下内容。我不熟悉如何把这个论坛的代码。。。这会引起一些麻烦

CREATE TABLE #MainTable ( 
        CustomerID INT  PRIMARY KEY, 
        FirstName VARCHAR(100) 
) 


DECLARE @Count INT
SET @Count = 0

DECLARE @Iterator INT
SET @Iterator = 0

WHILE @Count <8000
BEGIN

    INSERT INTO #MainTable SELECT @Count, "Cust"+CONVERT(VARCHAR(10),@Count)
    SET @Count = @Count+1

END

CREATE TABLE  #RightTable 
( 
        OrderID INT  PRIMARY KEY, 
        CustomerID INT, 
        Product VARCHAR(100) 
) 

CREATE INDEX  [IDX_CustomerID] ON #RightTable (CustomerID)

WHILE @Iterator <400000
BEGIN

        IF @Iterator % 2 = 0
        BEGIN

            INSERT INTO #RightTable  SELECT @Iterator,2, "Prod"+CONVERT(VARCHAR(10),@Iterator)
        END
        ELSE
        BEGIN
            INSERT INTO #RightTable  SELECT @Iterator,1, "Prod"+CONVERT(VARCHAR(10),@Iterator)
        END

SET @Iterator = @Iterator+1

END


-- Using LEFT JOIN

SELECT  mt.CustomerID,mt.FirstName,COUNT(rt.Product) [CountResult]
FROM    #MainTable mt 
        LEFT JOIN #RightTable rt ON mt.CustomerID = rt.CustomerID 
GROUP BY mt.CustomerID,mt.FirstName


---------------------------



-- Using Table variable Update


DECLARE @WorkingTableVariable TABLE
( 
        CustomerID INT, 
        FirstName VARCHAR(100),
        ProductCount INT  
) 

INSERT 
INTO @WorkingTableVariable (CustomerID,FirstName)
SELECT  CustomerID, FirstName FROM #MainTable 

UPDATE  @WorkingTableVariable 
SET     ProductCount = [Count]
FROM    @WorkingTableVariable wt 
        INNER JOIN
            (SELECT CustomerID,COUNT(rt.Product) AS [Count]
             FROM #RightTable rt
             GROUP BY  CustomerID) IV ON wt.CustomerID = IV.CustomerID 

SELECT CustomerID,FirstName, ISNULL(ProductCount,0) [CountResult] FROM    @WorkingTableVariable 
ORDER BY CustomerID

--------

DROP TABLE  #MainTable

DROP TABLE  #RightTable
谢谢
Lijo

在我看来,这样做有一个原因: 如果您有一个复杂的查询,其中包含许多内部联接和一个左联接,您有时会遇到麻烦,因为此查询的速度比使用没有左联接的同一查询要慢数百倍

如果查询大量记录,结果只有很少的记录要联接到左联接,那么如果将中间结果具体化为表变量或临时表,则可以获得更快的结果

但是通常不需要真正更新表变量中的数据-您可以使用左连接查询表变量以返回结果


。。。只有我的两分钱。

我创建了表格,并插入了值。然后,使用执行计划和探查器,左连接的性能优于@TABLE insert/update。更少的持续时间,读取和写入。因此,从我的快速分析来看,我宁愿使用左连接,也不愿使用@TABLE insert/update。此外,我宁愿修改原始问题。不要将答案作为问题发布给其他人。此外,对他们张贴的答案的评论将更容易引起他们的注意……这是一个城市神话。tempdb中存在表变量。检查这里的Q&A4:对于较新的版本仍然如此。@Frank Kalis-表变量在内存中不是城市神话吗?事实上,它们可以持久化到tempdb,这取决于内存压力等因素?不。它们存在于tempdb中,但它们所持有的数据也可能会或不会被持久化到tempdb中。对于任何永久、临时或表变量的表,分配映射中必须至少有一页,磁盘上必须有一个数据页。如果SQL Server在磁盘上的某个位置没有保留的相应页,则无法在缓冲池中有页。但是,表变量的数据页可能永远不会写入tempdb,但空间仍然存在。