0

我正在尝试构建一个表格来总结我们 Wiki 中的页面引用某些宏的次数。

我已经建立了一个名为 @currentpages 的临时表,它有 55k 行,如下所示:

DECLARE @currentpages table(
ContentID       NUMERIC(19,0) NOT NULL PRIMARY KEY,
PageTitle       VARCHAR(255) NULL,
SpaceKey            VARCHAR(255) NULL,
OriginalAuthor  VARCHAR(255) NULL,
LastChangedBy   VARCHAR(255) NULL,
LastChangedDt   VARCHAR(10) NULL,
ContentBody         TEXT NULL); 

和另一个看起来像这样的表:

DECLARE @usage table(
SpaceKey        VARCHAR(255) NOT NULL PRIMARY KEY,
Macro1      NUMERIC(19,0) NULL,
Macro2      NUMERIC(19,0) NULL,
Macro3              NUMERIC(19,0) NULL);

(我已经简化了上面的内容;它实际上有大约 40 列,如 Macro1、Macro2 等。)我试图计算有多少引用(在@currentpages 中)对这些不同的宏。

我通过为每个可能的 SpaceKey 值创建一行来初始化 @usage 表,将所有 Macro"x" 计数器清零:

INSERT INTO @usage (SpaceKey, Macro1, Macro2, Macro3)
SELECT S.spacekey, 0, 0, 0
FROM spaces     S
ORDER BY S.spacekey

然后我运行几个 UPDATE 语句中的第一个来识别每个宏引用:

UPDATE @usage
SET U.AdvancedSearch = C.Counter
FROM @usage                 U
INNER JOIN (SELECT SpaceKey, COUNT(*) AS Counter 
    FROM @currentpages 
    WHERE ContentBody LIKE '%{search-%' GROUP BY SpaceKey) C 
        ON U.SpaceKey = C.SpaceKey

这似乎工作正常,但运行时间很长。有没有更有效的方法来做我想做的事情?

此数据库位于 SQL Server 2005 上。

非常感谢,贝茜

4

3 回答 3

1
  1. 调查全文搜索。(全文搜索@MSDN)我没有这方面的经验,所以不能提供建议。

  2. 无需为每个宏查询一次@CurrentPages,而是一次获取所有宏计数。就像是:

    INSERT INTO @usage (SpaceKey, Macro1, Macro2, Macro3)
    SELECT S.spacekey
        , count(case when ContentBody LIKE '%Search Macro 1%' 
            then 1 else null end) as Macro1_Count
        , count(case when ContentBody LIKE '%Search Macro 2%' 
            then 1 else null end) as Macro2_Count
        , count(case when ContentBody LIKE '%Search Macro 3%' 
            then 1 else null end) as Macro=3Count
    FROM spaces S
    LEFT OUTER JOIN @CurrentPages C ON C.SpaceKey = S.SpaceKey
    GROUP BY S.spacekey
    
于 2011-08-03T10:34:28.890 回答
0

我想任何性能损失都将来自包含 LIKE 子句的子查询,因为它将进行全表扫描。我真的不知道还有什么会减慢这一速度。

您可以通过仅运行子查询并将返回所需的时间与您的一列的整个更新所需的时间进行比较来测试这一点。

于 2011-08-02T13:07:01.630 回答
0

不要为每个宏创建一列,而是创建一个这样的表。

DECLARE @macrotype table(
    type      int          NOT NULL PRIMARY KEY
  , MacroName varchar(100) NOT NULL 
  , mask      varchar(100) NOT NULL 
)

DECLARE @usage table(
  SpaceKey    VARCHAR(255) NOT NULL PRIMARY KEY,
, MacroType   int NOT NULL 
, MacroCount  int NOT NULL 
)

一旦你有了它,你可以通过运行来填充它

  INSERT INTO @macrotype VALUES (1, 'search', '%{search-%')
                              , (2, 'yadayada', '%{yadayada-%')
                              , ...

  DECLARE @c int, @m varchar(100)
  DECLARE c CURSOR READ_ONLY FOR SELECT type, mask FROM @macrotype
  OPEN c

  FETCH NEXT FROM c INTO @t, @m

  WHILE @@FETCH_STATUS = 0 
    BEGIN
      INSERT INTO @usage (SpaceKey, MacroType, MacroCount)
      SELECT SpaceKey
           , @t
           , COUNT(*) AS Counter 
        FROM @currentpages
       WHERE ContentBody LIKE @m
    GROUP BY SpaceKey
    FETCH NEXT FROM c INTO @t, @m
  END
  CLOSE c
  DEALLOCATE c

在您的故事结束时,您可以查询@usage 表以您希望的任何形式进行计数。

  SELECT MacroName, count = count(*)
    FROM @usage u
    JOIN @macrotype m
      ON u.MacroType - m.type
GROUP BY MacroName

在 55k 条记录上,这将运行几分钟。

于 2011-08-02T13:50:10.923 回答