0

我有一个 INNER JOIN 的更新。我的总体问题是如何(如果可能的话)将 LIMIT 和 OFFSET 设置为该连接表。

没有限制和偏移的示例查询:

UPDATE t2 
SET t2.some_col = t1.some_col
FROM table_1 t1
INNER JOIN table_2 t2
ON t1.other_col = t2.other_col

以及如何重建此查询以仅从 t2 获取前 1000000、1000000 - 2000000、2000000 - 3000000 等记录。

具体风景:

我的任务是使用散列索引 (char(32)) 将非常大的表重建为 bigint 索引。示例表:

URLS:                               PAGE_VIEWS:
id char(32)                         urlId char(32) 
other_columns                       referrerUrlId char(32) 
intUrlId bigint (added and filled)  other_columns 
                                    intUrlId bigint (needs to update)
                                    intReferrerUrlId bigint (needs to update)

第一个表大约有 2 亿条记录,第二个超过 10 亿条记录。我以包的形式更新此表。如果我可以使用 WHERE urls.intUrlId BETWEEN ...,更新工作不会很困难……但我不能。有时 JOIN 返回单个包的示例 500000 条记录,但很多时候它返回 0,因此它更新 0 条记录,但加入如此大的表会花费大量时间。所以我需要由 page_views 表而不是 urls 表限制的相等包。Page_views 表没有我可以基于 WHERE 子句的列,因此我需要通过 TOP 和 ROW_NUMBER() 子句限制此表,但我不知道如何。(我是 MsSQL 的新手,我曾经在具有 LIMIT 和 OFFSET 子句的 MySQL 和 PostgreSql 数据库上工作。

对于任何答案,我将不胜感激有关此解决方案成本的信息,因为有人会喜欢任何 LIMIT - OFFSET 解决方案,但不是我。我已经有查询更新了我需要的内容。但它使用 urls 表中的 intUrlId 并且速度很慢。我需要更快的解决方案。服务器版本 2008。

顺便提一句。不要问我到底是谁基于 char 索引的数据库 :-) 现在它变成了一个问题,需要重建多 TB 数据库。

4

2 回答 2

1

要回答 Jeremy 的答案表中的“如何设置 LIMIT、OFFSET 到连接表”的问题,需要切换。对于我在问题中使用的示例查询,我将给出正确答案。

WITH toUpdate AS
(
   SELECT some_col, other_col, ROW_NUMBER() OVER (ORDER BY any_column) AS RowNumber
   FROM table_2
) 
UPDATE toUpdate 
SET toUpdate.some_col = t1.some_col 
FROM table_1 t1 
INNER JOIN toUpdate ON t1.other_col = toUpdate.other_col
AND RowNumber BETWEEN 1000000 AND 2000000
于 2013-09-03T10:10:29.033 回答
1

您可以尝试使用带有 RowNumber 的 CTE

    WITH toUpdate AS
(
    SELECT urlId, intUrlId, ROW_NUMBER() OVER (ORDER BY something) AS RowNumber
    FROM [XXX].[ZZZ].[Urls] 
) 

UPDATE pv 
SET pv.intUrlId = urls.intUrlId 
FROM toUpdate urls
INNER JOIN [XXX].[YYY].[PageViews] pv WITH(NOLOCK) ON pv.urlId = urls.id and RowNumber between 10000 and 20000
于 2013-08-30T15:41:15.030 回答