2 votes

DANS LES INSTRUCTIONS CONTIENNENT DE NOMBREUSES VALEURS - TSQL

J'ai besoin de vos conseils.

J'ai une instruction CASE dans ma requête T-SQL comme ceci :

CASE 
    WHEN PLAN_GIVEN IN (cette liste contient 1700 valeurs à comparer) THEN 'P1'
    WHEN PLAN_GIVEN IN (cette liste contient 1800 valeurs à comparer) THEN 'P2'  
    ELSE NULL
END AS PLAN_NAME

Je ne peux pas énumérer toutes les 1700 valeurs IN ( ) THEN 'P1' car cela ne sera pas joli avec toutes ces valeurs.

J'ai essayé de sauvegarder les 1700 valeurs et les 1800 valeurs dans une lookup_table comme ceci

lookup_table  

columnA = toutes les 1700 valeurs                 
columnB = toutes les 1800 valeurs

et j'ai utilisé cette requête :

CASE 
    WHEN PLAN_GIVEN IN (SELECT columnA from lookup_table) THEN 'P1'
    WHEN PLAN_GIVEN IN (SELECT columnB from lookup_table) THEN 'P2'  
    ELSE NULL
END AS PLAN_NAME

Le code ci-dessus fonctionne mais il prend plus de temps pour s'exécuter, presque 10 minutes pour compléter l'exécution.

Y a-t-il une autre façon d'atteindre cela ?

3voto

Au lieu d'utiliser PLAN_GIVEN IN, essayez d'utiliser EXISTS :

CASE 
    WHEN EXISTS (SELECT NULL from lookup_table WHERE PLAN_GIVEN = columnA) 
         THEN 'P1'
    WHEN EXISTS (SELECT NULL from lookup_table WHERE PLAN_GIVEN = columnB) 
         THEN 'P2'  
ELSE NULL
END AS PLAN_NAME

Alternativement, essayez de joindre votre table de recherche et de comparer avec les valeurs de recherche dans votre expression CASE :

SELECT ...
       CASE PLAN_GIVEN
           WHEN lookup_table.columnA THEN 'P1'
           WHEN lookup_table.columnB THEN 'P2'  
           ELSE NULL
       END AS PLAN_NAME
       ...
FROM ...
LEFT JOIN lookup_table 
  ON PLAN_GIVEN IN (lookup_table.columnA, lookup_table.columnB)

3voto

Andriy M Points 40395

Je changerais la table de recherche pour quelque chose comme ceci :

Valeur  Nom
-----  ----
123    P1
456    P1
...    ...
789    P2
...    ...

avec l'index clusterisé sur Valeur.

Après cela, vous pouvez simplement faire une jointure externe de la table de recherche sur LookupTable.Value = _otherTable_.PLAN_GIVEN et simplement récupérer LookupTable.Name dans la clause SELECT, c'est-à-dire quelque chose comme ceci :

SELECT
  ...
  lookup.Name AS PLAN_NAME,
  ...
FROM
  ...
  LEFT OUTER JOIN LookupTable lookup ON lookup.Value = otherTable.PLAN_GIVEN
WHERE...
...

Veuillez noter que je suppose que les valeurs de recherche sont uniques, ce qui me semblait être naturel étant donné la façon dont vous les traitiez dans votre expression CASE.

1voto

Kenneth Fisher Points 3462

Tout d'abord, utilisez l'une des solutions que @MarkBannister a données. Ensuite, mettez des index sur chaque colonne de votre table de recherche.

 CREATE INDEX IX_lookup_table_A ON lookup_table(columnA)
 CREATE INDEX IX_lookup_table_B ON lookup_table(columnB)

Même si lookup_table est une table temporaire, il vaut quand même la peine d'ajouter les index. Et si c'est une table statique, alors cela en vaut vraiment la peine.

0voto

Blam Points 17325

Vaut la peine d'essayer

select 'P1' 
from table 
where PLAN_GIVEN IN (cette liste contient 1700 valeurs à comparer) 
union 
select 'P2' 
from table 
where PLAN_GIVEN IN (cette liste contient 1800 valeurs à comparer) 

Si PLAN_GIVEN a un index alors cela pourrait utiliser l'index.
Je ne pense pas que CASE puisse utiliser un index.

Peut-être TVP plutôt que in

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X