0

我有一个大的用户 ID 表和另一个用户记录表,其中包含带有用户 ID 的用户帖子。该过程是每当检索到新的提要帖子时,我都会向用户 id 表请求一个标记为非活动的 id(我有该字段 ACTIVE,因为我有另一个进程创建这些 id 并将其连续插入到表 1 中)并且当请求一个 id 时,它被标记为非活动状态。然后我检查用户表(表 2)中是否存在用户,如果存在则返回与该用户关联的用户 ID。

有人告诉我,我可以加快这个过程,但创建一个哈希表来查找表 2。我什至不知道如何开始这个,任何链接或示例将不胜感激。我还需要运行一个单独的进程来清理表 1 并删除所有非活动用户 ID。

当我调用插入表 2 的过程时,我传递了从表 1 中检索到的用户 ID。

CREATE TABLE [dbo].[userforums]
  (
     [userid]       [VARCHAR](16) NOT NULL  CONSTRAINT [PK_forumssiteid] PRIMARY KEY CLUSTERED ,
     [forumname]    [VARCHAR](500) NOT NULL,
     [exported]     [INT] NULL,
     [lastcrawled]  [DATETIME] NULL,
     [priority]     [INT] NULL,
     [origin]       [VARCHAR](50) NULL,
     [queryid]      [VARCHAR](25) NULL,
     [dateinserted] [DATETIME] NULL DEFAULT (getdate()) 
   )

第二张桌子

CREATE TABLE [dbo].[userids]
  (
     [userid] [NVARCHAR](20) NOT NULL CONSTRAINT [PK_userids] PRIMARY KEY CLUSTERED,
     [active] [NVARCHAR](20) NULL  CONSTRAINT [IX_userids] UNIQUE NONCLUSTERED 
  )

获取用户id存储过程

BEGIN TRANSACTION

SELECT TOP 1 @id = userid
FROM   userids WITH (UPDLOCK, HOLDLOCK)
WHERE  active = 'Y'
        OR active IS NULL

UPDATE userids
SET    active = 'N'
WHERE  userid = @id

COMMIT TRANSACTION 

检查用户标识是否存在

CREATE PROC Foo @forumname VARCHAR(500),
                @userid    VARCHAR(16),
                @origin    VARCHAR(50),
                @queryid   VARCHAR(25)
AS
    SET NOCOUNT ON;

    DECLARE @cnt INT
    DECLARE @serverip VARCHAR(16)
    DECLARE @mincnt INT
    DECLARE @siteservercnt INT

    SELECT @cnt = COUNT(*)
    FROM   userforums
    WHERE  forumname = @forumname

    IF @cnt = 0
      BEGIN
          INSERT INTO userforums
                      (forumname,
                       userid,
                       exported,
                       origin,
                       queryid)
          VALUES     (@forumname,
                      @userid,
                      1,
                      @origin,
                      @queryid)

          SELECT @siteservercnt = COUNT(*)
          FROM   siteserverip
          WHERE  userid = @userid

          IF @siteservercnt = 0
            BEGIN
                SELECT TOP 1 @mincnt = COUNT(*),
                             @serverip = serverip
                FROM   siteserverip
                GROUP  BY serverip
                ORDER  BY COUNT(*)

                SELECT TOP 1 @mincnt = sitecount,
                             @serverip = serverip
                FROM   serveripcounts
                ORDER  BY sitecount

                INSERT INTO siteserverip
                VALUES     (@siteid,
                            @serverip)

                UPDATE serveripcounts
                SET    sitecount = sitecount + 1
                WHERE  serverip = @serverip
            END
      END

    SELECT userid
    FROM   userforums
    WHERE  forumname = @forumname

    RETURN 
4

2 回答 2

2

您现有的出列查询可以改进。代替

DECLARE @id INT

SELECT TOP 1 @id = userid
FROM   userids WITH (UPDLOCK, HOLDLOCK)
WHERE  active = 'Y'
        OR active IS NULL

UPDATE userids
SET    active = 'N'
WHERE  userid = @id

您可以执行哪两个操作(聚集索引扫描后跟索引查找)

UPDATE TOP (1) userids  
WITH (ROWLOCK, READPAST)
SET  active = 'N'
OUTPUT INSERTED.userid
WHERE  active <> 'N'

这是一项操作,并给出了一个具有两个范围搜索的计划。

于 2013-01-18T21:00:43.970 回答
-1

哈希表 #TableName 是 tempdb 中用作表的临时对象。它们通常被称为“临时表”。如果这种情况很常见,我不会将它们用作即时检索数据的第一个解决方案。相反,我会创建一个索引,看看这是否能证明您的需求。通常,哈希表用于密集操作,您希望获取一组可能会或可能不会被索引的事物,然后将其与其他事物相关联,并且您希望将其保存在内存中。

我会创建一个索引,这应该会提高速度。此外,如果您发现速度很慢,则哈希表不会加快该部分的速度,它只会将其集合放入源中以与主表分开重用。

create index IX_[yourtableName]_[TableColumn(s)] on [Tablename]([Column(s)]

除非必要,否则我不会创建更多对象。通常,如果您的 UserId 是有效的整数,您可以非常快速地搜索它们。

于 2013-01-18T20:07:36.577 回答