SQL - 临时表:存储临时表中的所有列与仅存储主键

时间:2008-12-09 15:01:07

标签: sql sql-server sql-server-2005

我需要创建临时表以进行分页。我将所有记录选入临时表,然后用它进行进一步处理。

我想知道以下哪项是更好的方法:

1)选择我的主表的所有列到临时表中,然后能够选择我需要的行

OR

2)只选择主表的主键进入临时表,然后再加入主表?

使用方法1与方法2时是否有任何规模考虑?

[编辑]

我问,因为我会做第一种方法,但是看看PROCEDURE [dbo]。[aspnet_Membership_FindUsersByName],它包含在ASP.NET成员资格中,他们正在做方法2

[EDIT2]

如果人们无法访问存储过程:

  -- Insert into our temp table
INSERT INTO #PageIndexForUsers (UserId)
    SELECT u.UserId
    FROM   dbo.aspnet_Users u, dbo.aspnet_Membership m
    WHERE  u.ApplicationId = @ApplicationId AND m.UserId = u.UserId AND u.LoweredUserName LIKE LOWER(@UserNameToMatch)
    ORDER BY u.UserName


SELECT  u.UserName, m.Email, m.PasswordQuestion, m.Comment, m.IsApproved,
        m.CreateDate,
        m.LastLoginDate,
        u.LastActivityDate,
        m.LastPasswordChangedDate,
        u.UserId, m.IsLockedOut,
        m.LastLockoutDate
FROM   dbo.aspnet_Membership m, dbo.aspnet_Users u, #PageIndexForUsers p
WHERE  u.UserId = p.UserId AND u.UserId = m.UserId AND
       p.IndexId >= @PageLowerBound AND p.IndexId <= @PageUpperBound
ORDER BY u.UserName

5 个答案:

答案 0 :(得分:2)

表变量优先于临时表,如果它在您的约束范围内。

选项2将使用更少的资源,因为数据重复较少。

托尼关于这是一个肮脏的阅读的观点是你应该考虑的事情。

你能解释一下你如何用临时表'分页'吗?它不是我熟悉的分页方法。

编辑: 查看帖子编辑后,在这种情况下,您应该肯定使用表变量。它不太清理,你不会这么多地吹掉tempdb。

此外,还不清楚这个临时表给出了什么好处。如果您的目标是阻止用户访问对象/应用程序,那么为什么要添加关于它的部分“仅在此特定数据表页面上受限制”。从安全角度来看,这似乎是一种漏洞。

临时表也几乎可以消除,因为它从相同的表中选择。

答案 1 :(得分:1)

使用方法1,临时表中的数据可能与实际数据不一致,即,如果其他会话对实际数据进行了更改。如果您只是查看在某个点获取的数据的快照,这可能没问题,但如果您还根据对临时副本所做的更改来更新实际表,则会很危险。

答案 2 :(得分:0)

这正是我在服务器上使用Paging的方法,

创建一个表变量(为什么会产生事务记录的开销?)只使用键值。 (使用autonum标识列主键创建表 - 这将是RowNum。)

根据用户排序/过滤条件将密钥插入表中。标识列现在是一个可用于分页的行号。

从表变量中选择加入其他需要真实数据的表,加入键值

Where RowNum Between ((PageNumber-1) * PageSize) + 1 And PageNumber * PageSize

答案 3 :(得分:0)

以这种方式思考。假设您的查询将返回足够的记录来填充1000页。您认为有多少用户真正关注所有这些页面?只返回ID,您不会返回很多您可能需要或可能不需要查看的信息。所以它应该节省网络和服务器资源。如果他们确实经历了很多页面,那么确实需要刷新数据细节需要花费足够的时间。

答案 4 :(得分:0)

分页的替代方式(我公司的方式)是使用CTE。

http://softscenario.blogspot.com/2007/11/sql-2005-server-side-paging-using-cte.html

查看此示例
CREATE PROC GetPagedEmployees (@NumbersOnPage INT=25,@PageNumb INT = 1)
AS BEGIN

WITH AllEmployees AS
(SELECT ROW_NUMBER() OVER (Order by [Person].[Contact].[LastName]) AS RowID,
[FirstName],[MiddleName],[LastName],[EmailAddress] FROM [Person].[Contact])

SELECT [FirstName],[MiddleName],[LastName],[EmailAddress]
FROM AllEmployees WHERE RowID BETWEEN
((@PageNumb - 1) * @NumbersOnPage) + 1 AND @PageNumb * NumbersOnPage
ORDER BY RowID