Bonjour à tous,
Le logiciel sur lequel je travaille (Apriso) a un type de grille où l'on peut déterminer la requête qui va être exécuté.
Il est possible de filtrer les résultats sur une colonne ce qui a pour effet de re-exécuter la requête après lui avoir ajouté le prédicat correspondant au filtre.
Par exemple, on a cette requête :
1 2 3 4
| SELECT *
FROM INVENTORY2_HISTORY_HEADER I2HH
JOIN INVENTORY2_HISTORY_DETAIL I2HD
ON I2HH.ID = I2HD.InventoryHistoryHeaderID |
(J'ai simplifié le SELECT mais en réalité la requête récupère quasiment tous les champs)
On filtre sur la colonne WipOrderNo avec la valeur 4631768
-> la ligne suivante est ajouté à la requête (récupérée via l'activity monitor):
WHERE (( ( I2HH.ACTIVE = N'1' ) AND ( I2HD.WipOrderNo LIKE N'%4631768%' ESCAPE '\' ) ) ) ORDER BY I2HH.ID ASC, I2HD.ID ASC
Le problème est que la partie "ESCAPE '\'" change le plan d'exécution et fait passer le temps d'exécution d'environ 6s à 56s.
Dans le cas où on retire la partie escape, SQL fait un scan de l'index clusterisé avec le prédicat sur le WipOrderNo :
![Nom : Normal.png
Affichages : 109
Taille : 67,4 Ko](https://www.developpez.net/forums/attachments/p642646d1692176546/bases-donnees/langage-sql/escape-change-plan-d-execution/normal.png/)
Dans l'autre cas, SQL fait un scan sur l'index non-clusterisé (qui est sur le champs Inventory2HistoryHeaderID) sans aucun prédicat (6 436 798 lignes) et fait un key-lookup avec cette fois-ci le prédicat (27 lignes).
Ensuite il fait des nested loops sur ces résultats, ce qui prend plus de 50s.
![Nom : Escaped.png
Affichages : 107
Taille : 37,6 Ko](https://www.developpez.net/forums/attachments/p642648d1692178094/bases-donnees/langage-sql/escape-change-plan-d-execution/escaped.png/)
Le problème est qu'on ne peut pas virer l'escape, il s'agit du comportement de base d'Apriso.
En incluant le champs qui est filtré dans l'index qui est utilisé avec l'échappement on retombe sur de bonnes performances mais je trouves ça un peu dommage de devoir inclure tous les champs qui vont être amené à être filtré.
Est-ce que vous avez une idée de pourquoi le fait d'échapper un caractère peut modifier le plan d'exécution ? (Et si vous avez une meilleure solution)
Merci beaucoup de votre attention !
Partager