Question

Un de mes anciens collègues a écrit le UPDATE suivant dans le cadre d'un script d'importation de données. Il faut près de 15 minutes pour terminer sur une table de 92 000 lignes.

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
);

Je suis sûr qu'il peut être réécrit pour être plus efficace, mais toutes mes tentatives ont échoué ou n'ont pas donné les mêmes résultats.

De plus, aucun index n'est défini sur la table. Suggestions appréciées. Je suis sur Sybase iAnywhere 11 si cela compte.

Était-ce utile?

La solution

Mettez un index sur old_Name et voyez le temps qu'il faut tel quel ...

Deuxièmement, en analysant votre requête, il semble y avoir une faille dans celle-ci. si vous regardez la version reformatée ci-dessous,

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);

L'avant-dernière ligne WHERE t.old_name = table.old_name fera en sorte que la sous-requête interne ne comporte que des lignes avec t.oldname = avec la valeur de requête table.nom_old. Donc, peu importe que vous fassiez un Top 1 ou non, puisque toutes les lignes auront la même valeur pour old_name, vous définissez toujours la valeur exactement comme elle est déjà, non ??

EDIT: (basé sur la clause Where), essayez ceci:

 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);

Autres conseils

Je ne suis pas une personne Sybase, mais je le ferais de la manière suivante.

Pseudo Sql Cela devrait éliminer votre SELECT récursif

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top