Je vous sollicite au sujet d'une requête qui me donne quelques soucis.
Le premier point à considérer, c'est que je ne peux pas en changer la structure des tables, ni influer sur les règles de gestion précisées ci-dessous. Je peux juste jouer sur la requête et les index.
La requête a pour but de déterminer le prix d'un article, sachant que le prix peut être :
> unique par site ou bien le même pour tous les sites
> unique par dimension (couleur, taille, etc.) ou bien le même pour toutes les dimensions de l'article
De plus on recherche le dernier prix pour cet article en terme de date de création, sachant qu'il peut bien évidemment avoir un historique de plusieurs prix.
En fait, c'est cette triple hypothèse qui va me poser des problèmes de perf lors de l'exécution de la requête de recherche de prix, même si le nombre d'articles et de prix n'est vraiment pas démentiel (23 000 articles et 33 000 prix).
Voici les champs de la table utilisés dans la requête :
Si le champ SITE='A', cela veut dire que le prix est spécifique au site A.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 CREATE TABLE ARTICLEPRIX ( SITE CHAR(1) --> site auquel le prix est à appliquer ARTICLE CHAR(2) --> code de l'article DATE SMALDATETIME --> date de début du prix PRIX INTEGER --> prix de l'article pour un site et une date donnés )
Si le champ SITE='', cela veut dire que le prix est commun à l'ensemble des sites.
Article non dimensionné : ARTICLE='1 ' où '1' est le code de l'article et ' ' signifie qu'il n'a pas de dimension
Article dimensionné : ARTICLE='2G' où '2' est le code de l'article et 'G' correspond à la dimension G.
Si pour l'article n°3 dimensionné, le prix est commun à l'ensemble des dimensions, alors une seule ligne de prix est crée avec ARTICLE='3 ' (donc comme pour un article non dimensionné)
Si pour un article n°4 dimensionné, le prix est spécifique pour une ou plusieurs dimensions, alors une ligne de prix est crée par dimension avec un prix spécifique (ARTICLE='4A', ARTICLE='4B', ARTICLE='4C', etc.) et une ligne est crée pour toutes les autres dimensionnés qui ont un prix commun (ARTICLE='4 ').
Ces règles un peu mieux précisées, voici la requête :
La requête en elle-même semble toute bête mais les deux clauses (SITE=[le site à chercher] OR SITE='') et (ARTICLE=[code de l'article] OR ARTICLE=LEFT([code de l''article],1) + ' ') augmentent les temps de traitement de façon exponentielle. Par contre si l'on utilise uniquement l'une ou l'autre, les temps de traitement chutent énormément.
Code : Sélectionner tout - Visualiser dans une fenêtre à part SELECT TOP 1 PRIX FROM ARTICLEPRIX WHERE (SITE=[le site à chercher] OR SITE='') AND (ARTICLE=[code de l''article] OR ARTICLE=LEFT([code de l''article],1) + ' ') AND DATE <= [date à chercher] ORDER BY DATE DESC, ARTICLE DESC, SITE DESC
La base tourne sur un SQL Server 2000.
En terme d'index, j'ai créé celui-ci qui est parfaitement inefficace :
Pour donner un ordre d'idée, pour 100 articles, la requête prend 1.5s, mais pour 1000 articles elle prend 38s. Je vous laisse deviner pour 10000 articles ....
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 CREATE INDEX X_PRIX_INDEX1 ON ARTICLEPRIX (ARTICLE ASC, SITE ASC, DATE DESC)
Auriez-vous une idée sur la façon d'optimiser la requête ou d'indexer plus efficacement la table ? Merci d'avance.
Partager