Pour les performances Sql, plusieurs égales ou une entre

Pour un nouveau développement, j'aurai une grosse table SQL (~ 100M lignes). 4 champs seront utilisés pour interroger datatables.

Est-il préférable d'interroger un champ concaténé avec entre ou plusieurs égaux?

Exemple:

MainTable

 PkId |  Label |  FkId1 |  FkId2 |  FkId3 |  FkId4
 1 |  test |  1 |  4 |  3 |  1

Les données dans les tables FK sont statiques, exemple:

FkTable1

 Id |  Valeur
 1 |  une
 2 |  b
 3 |  c 

Pour interroger datatables, la requête SQL classique est:

select Label, FkId1, FkId2, FkId3, FkId4 from MainTable where FkId1=1 and FkId2=2 and FkId3 in(2, 3) 

L'idée d'optimiser les performances est d'append un champ "UniqueId" backend calculé avant l'insertion:

 UniqueId = FkId1*1000000 + FkId2*10000 + FkId3*100 + FkId4 
 PkId |  Label |  FkId1 |  FkId2 |  FkId3 |  FkId4 |  Identifiant unique
 1 |  test |  1 |  4 |  3 |  1 |  1040301
 select Label, FkId1, FkId2, FkId3, FkId4 from MainTable where UniqueId between 1020200 and 1040000 

De plus, avec le champ UniqueId, un index sur ce champ sera suffisant.

Qu'est-ce que tu penses ?

Merci

Pour cette requête:

 select Label, FkId1, FkId2, FkId3, FkId4 from MainTable where FkId1 = 1 and FkId2 = 2 and FkId3 in (2, 3) 

L'index optimal est sur MainTable(FkID1, FkId2, FkId3) . Vous pouvez également append Label et FkId4 à l'index si vous souhaitez un index de couverture (de sorte que l'index puisse gérer l'set de la requête sans faire reference aux pages de données d'origine).

Il n'y a pas besoin d'un champ calculé pour l'exemple que vous avez fourni.

Puisque vous aurez 100M lignes, penser à des optimizations dès le départ me semble raisonnable. Cependant, votre solution proposée ne fonctionnera pas de cette manière:

  1. Votre formule ci-dessus a deux fois le même facteur 10000. Vous devez utiliser des facteurs différents, à savoir des puissances différentes de 10.

  2. Votre exemple de sélection a une clause "IN" (FkId3 in (2, 3)). Cela ne fonctionnera que si un seul des FK est interrogé de cette façon. Ce fk devrait être celui sans facteur dans la formule pour calculer UniqueId (c'est-à-dire donne les numbers les less significatifs de UniqueId).

Maintenant, en voyant Gordons répondre, je suis d'accord avec lui, c'est-à-dire que l'utilisation d'un index combiné peut être assez bon pour vous (bien que votre solution serait probablement légèrement meilleure). Cependant, l'index combiné a également un problème similaire: le champ FK en cours d'interrogation avec la clause IN doit être le dernier champ de l'index.