【问题标题】:Slow SQL update could use some help缓慢的 SQL 更新可能需要一些帮助
【发布时间】:2009-09-17 03:36:13
【问题描述】:

我的一位前同事写了以下 UPDATE 作为数据导入脚本的一部分,在 92k 行的表上完成需要将近 15 分钟。

UPDATE table
SET name = (
    SELECT TOP 1 old_name FROM (
        SELECT 
            SUM(r) rev,
            number,
            name, 
            intermediate_number,
            intermediate_name,
            old_number,
            old_name
        FROM table
        GROUP BY 
            number,
            name, 
            intermediate_number,
            intermediate_name,
            old_number,
            old_name 
    ) t
    WHERE t.name = table.name
    ORDER BY rev DESC
);

我确信它可以被重写以提高效率,但我所有的尝试都失败了,或者没有产生相同的结果。

此外,表上没有定义索引。建议表示赞赏。如果这很重要,我在 Sybase iAnywhere 11 上。

【问题讨论】:

  • intermediate_number 可以使用一些微调器。

标签: sql optimization sybase query-optimization


【解决方案1】:

在 old_Name 上放一个索引,看看它需要多长时间......

其次,在分析您的查询时,它似乎存在缺陷。如果您查看下面的重新格式化版本,

UPDATE table SET 
    name = (SELECT TOP 1 old_name 
            FROM (SELECT SUM(r) rev, number, name,
                    intermediate_number, intermediate_name,
                    old_number, old_name
                  FROM table
                  GROUP BY number, name, intermediate_number, 
                       intermediate_name, old_number, old_name) t 
            WHERE t.old_name = table.old_name  -- HERE
            ORDER BY rev DESC);

倒数第二行 WHERE t.old_name = table.old_name 将导致内部子查询只有 t.oldname = 到外部值的行查询 table.old_name。所以,你是否做 Top 1 并不重要,因为所有的行都将具有相同的 old_name 值,你将始终将值设置为它已经存在的值,不??

编辑:(基于 Where 子句更改)试试这个:

 UPDATE table SET 
    name =  (SELECT Top 1 old_name
             FROM table it
             Where it.name = table.old_name
             GROUP BY number, intermediate_number, 
                      intermediate_name, old_number, old_name
             Order By SUM(r) Desc);

【讨论】:

  • 我刚刚编辑过,WHERE 子句错误,比较实际上是在 name 列上,所以我将尝试在其上添加索引。
  • 执行时间:163.707 秒:D
【解决方案2】:

我不是 Sybase 人,但我会按照以下方式进行操作。

伪 Sql

DECLARE @tempTable TABLE --In memory table if possible

INSERT INTO @tempTable
  SELECT
            SUM(r) rev,
            number,
            name,
            intermediate_number,
            intermediate_name,
            old_number,
            old_name        
  FROM table        
  GROUP BY
            number,
            name,
            intermediate_number,
            intermediate_name,
            old_number,
            old_namet
  ORDER BY rev DESC


UPDATE table
  SET name = SELECT TOP 1 old_name FROM @tempTable t WHERE t.old_name = table.old_name

这应该消除你的递归 SELECT

【讨论】:

    猜你喜欢
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 2017-09-27
    • 2011-08-07
    • 1970-01-01
    • 2010-12-16
    • 2011-03-26
    相关资源
    最近更新 更多