Une mise à jour lente de SQL pourrait utiliser de l'aide
-
07-07-2019 - |
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.
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