SQL Server – Indexer une table de mappage avec une plage min et max

J'ai un problème avec les performances quand il s'agit d'utiliser une table de mappage qui a plusieurs plages. La table de mappage est présentée comme suit.

ResultNumber param1Min param1Max param2Min param2Max ... param8min param8max 

Ce sont les noms de colonne de la table de mappage. Ce qui est joint sur la table est param1, param2, param3 ... param8 .

J'ai besoin de find la ligne où (param1 est entre param1Min et param1Max) et (param2 est entre param2Min et param2Max) … et get le numéro de résultat de la ligne correspondante. Le problème est que la table de mappage contient plus de 2 millions de lignes et que j'ai de la difficulté à indexer cette table car elle doit utiliser des plages pour find ce dont elle a besoin.

Des idées sur la façon d'accélérer cela?

J'ai également inclus l'index que j'ai essayé qui n'a pas aidé du tout

 SELECT ResultNumber FROM MappingTable WHERE ( param1 BETWEEN param1Min AND param1Max ) AND ( param2 BETWEEN param2Min AND param2Max ) AND ( param3 BETWEEN param3Min AND param3Max ) ... CREATE CLUSTERED INDEX [index] ON [dbo].MappingTable ( [param1Min] ASC, [param1Max] ASC, [param2Min] ASC, [param2Max] ASC, [param3Min] ASC, [param3Max] ASC, )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 

Les variables "param1, param2, param3 … param8" sont-elles dans une autre table? Dans tous les cas, je le splitais en morceaux pour extraire l'utilisation des index et couper le travail qui doit être fait à chaque vérification de paramètre suivante.

Vous voulez créer un index clusterisé sur resultnumber et seulement resultnumber, puis créer des index non cluster sur les combinaisons resultnumber, param # min, param # max. Doit être un total de 9 index sur [dbo]. [MappingTable].

 Create Clustered Index ix_rn On [dbo].[MappingTable] (resultnumber) Create NonClustered Index ix_p1 On [dbo].[MappingTable] (resultnumber, param1min, param1max) ... Create NonClustered Index ix_p8 On [dbo].[MappingTable] (resultnumber, param8min, param8max) 

Cela vous permettra d'get des gains de performance à partir du code ci-dessous. Cela devrait fonctionner extrêmement vite.

 With param1 As ( Select resultnumber From [dbo].[MappingTable] Where @param1 Between param1min And param1max ), param2 As ( Select m.resultNumber From [dbo].[MappingTable] m Join param1 p1 On m.resultnumber = p1.resultnumber Where @param2 Between param2min And param2max ), param3 As ( ... ... ), param8 As ( Select m.resultNumber From [dbo].[MappingTable] m Join param7 p7 On m.resultnumber = p7.resultnumber Where @param8 Between param8min And param8max ) Select resultNumber From param8 

Une implémentation de table ressemblerait à ceci. Cela prendrait encore un certain time en fonction de la taille de la table que vous rejoignez, mais elle devrait quand même fonctionner plus vite que votre requête d'origine.

 With param1 As ( Select m.resultnumber, w.tableIdentityValue From [dbo].[MappingTable] m Join whateverJoinTable w On w.param1 Between m.param1min And m.param1max ), param2 As ( Select m.resultNumber, w.tableIdentityValue From [dbo].[MappingTable] m Join param1 p1 On m.resultnumber = p1.resultnumber Join whateverJoinTable w On m.tableIdentityValue = w.tableIdentityValue And w.param2 Between m.param2min And m.param2max ), param3 As ( ... ... ), param8 As ( Select m.resultNumber, w.tableIdentityValue From [dbo].[MappingTable] m Join param7 p7 On m.resultnumber = p7.resultnumber Join whateverJoinTable w On m.tableIdentityValue = w.tableIdentityValue And w.param8 Between m.param8min And m.param8max ) Select resultNumber, tableIdentityValue From param8