Mysql
 sql >> Base de données >  >> RDS >> Mysql

Indexation correcte lors de l'utilisation de l'opérateur OU

Vous comprenez mal le fonctionnement des index.

Pensez à un annuaire téléphonique (l'équivalent d'un index à deux colonnes sur le nom de famille en premier, le prénom en dernier). Si je vous demande de trouver toutes les personnes dans l'annuaire téléphonique dont le nom de famille est "Smith", vous pouvez bénéficier du fait que les noms sont classés de cette façon; vous pouvez supposer que les Smith sont organisés ensemble. Mais si je vous demande de trouver toutes les personnes dont le prénom est "John", vous ne tirez aucun avantage de l'index. Johns peut avoir n'importe quel nom de famille, ils sont donc éparpillés dans tout le livre et vous finissez par devoir chercher à la dure, d'une couverture à l'autre.

Maintenant, si je vous demande de trouver toutes les personnes dont le nom de famille est "Smith" OU dont le prénom est "John", vous pouvez trouver les Smith facilement comme avant, mais cela ne vous aide pas du tout à trouver les Johns. Ils sont toujours éparpillés dans le livre et vous devez les rechercher à la dure.

C'est la même chose avec les index multi-colonnes en SQL. L'index est trié par la première colonne, puis trié par la deuxième colonne en cas d'égalité dans la première colonne, puis trié par la troisième colonne en cas d'égalité dans les deux premières colonnes, etc. Il n'est pas trié par toutes les colonnes simultanément. Ainsi, votre index multi-colonnes n'aide pas à rendre vos termes de recherche plus efficaces, à l'exception de la colonne la plus à gauche de l'index.

Revenez à votre question d'origine.

Créez un index séparé à colonne unique sur chaque colonne. L'un de ces index sera un meilleur choix que les autres, basé sur MySQL estimation du nombre d'opérations d'E/S l'index encourra s'il est utilisé.

Les versions modernes de MySQL ont également quelques astuces sur la fusion d'index , donc la requête peut utilisez plusieurs index dans une table donnée, puis essayez de fusionner les résultats. Sinon, MySQL a tendance à se limiter à utiliser un index par table dans une requête donnée.

Une autre astuce que beaucoup de gens utilisent avec succès consiste à effectuer une requête distincte pour chacune de vos colonnes indexées (qui doivent utiliser l'index respectif), puis UNION les résultats.

SELECT fields FROM table WHERE field1='something' 
UNION
SELECT fields FROM table WHERE field2='something' 
UNION
SELECT fields FROM table WHERE field3='something' 
UNION
SELECT fields FROM table WHERE field4='something' 

Une dernière observation :si vous vous retrouvez à rechercher le même 'something' sur quatre champs, vous devez reconsidérer si les quatre champs sont en fait la même chose, et vous êtes coupable de concevoir une table qui viole la première forme normale avec des groupes répétés . Si tel est le cas, les champs 1 à 4 appartiennent peut-être à une seule colonne d'une table enfant. Il devient alors beaucoup plus facile d'indexer et d'interroger :

SELECT fields from table INNER JOIN child_table ON table.pk = child_table.fk
WHERE child_table.field = 'something'