Медленное обновление SQL может использовать некоторую помощь - PullRequest
0 голосов
/ 16 сентября 2009

Мой бывший сотрудник написал следующее UPDATE как часть сценария импорта данных, и на обработку таблицы из 92 тыс. Строк требуется около 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, если это имеет значение.

Ответы [ 2 ]

3 голосов
/ 16 сентября 2009

Поместите индекс на 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 = значением внешней таблицы запросов .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);
0 голосов
/ 16 сентября 2009

Я не человек Sybase, однако я бы сделал это следующим образом.

Psudo 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

...