【问题标题】:SQL - Temp Table: Storing all columns in temp table versus only Primary keySQL - 临时表:将所有列存储在临时表中,而不是只存储主键
【发布时间】:2008-12-09 15:01:07
【问题描述】:

我需要为分页目的创建一个临时表。我会将所有记录选择到一个临时表中,然后对其进行进一步处理。

我想知道以下哪种方法更好:

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

2) 只选择Primary Table的主键进入Temp Table,稍后再加入Primary Table?

在使用方法 1 和方法 2 时是否有任何尺寸考虑?

[编辑]

我之所以问,是因为我会使用第一种方法,但查看 ASP.NET 成员资格中包含的 PROCEDURE [dbo].[aspnet_Membership_FindUsersByName],他们正在使用方法 2

[编辑2]

对于无法访问存储过程的人:

  -- 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

【问题讨论】:

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


    【解决方案1】:

    如果您的行数非常多(超过 100 行),那么表变量的性能通常会比等效的临时表差。但要测试它以确保。

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

    Tony 关于这是一个脏读的观点确实是你应该考虑的。

    【讨论】:

    • 我已将其包含在上面的问题中
    【解决方案2】:

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

    【讨论】:

    • 除了陈旧数据,还有其他区别吗?
    【解决方案3】:

    这正是我在服务器上用于分页的方法,

    仅使用键值创建表变量(为什么会产生事务日志的开销?)。 (使用自动编号标识列主键创建表 - 这将是 RowNum。)

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

    从表变量中选择连接到需要真实数据的其他表,在键值上连接,

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

    【讨论】:

    • 知道为什么 ASP.Net 成员使用临时表与表变量...可能是另一个问题...
    • 怎么样,涉及安全的时候为什么要分页?
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      分页的替代方法(我公司的做法)是使用 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-21
        • 2011-03-02
        • 1970-01-01
        • 1970-01-01
        • 2015-12-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多