En fait, votre clé primaire a peu de sens en termes de requête de plage. Il indique uniquement des paires uniques pour <from_ip, to_ip>
tuple - ainsi, MySQL ne pourra pas utiliser cet index avec de telles comparaisons de plages.
À moins que vous n'exécutiez une requête impliquant les deux parties de votre clé primaire, cela n'aura aucun effet (en fait, MySQL l'utilisera également - lorsque la condition de sélection utilise sous-ensemble gauche de l'index composé , mais ce n'est pas votre cas). Par exemple, cela utilisera la clé primaire :
-- @x and @y are derived from somewhere else
SELECT * FROM inetnum WHERE [email protected] && [email protected]
Dans votre cas, la clé composée peut être la clé primaire, oui, mais son seul avantage sera - de fournir l'unicité. Ainsi, vous pouvez le laisser tel quel ou créer un substitut id
clé primaire (en remplaçant la clé primaire actuelle par UNIQUE
contrainte).
L'une des solutions possibles pour améliorer la situation pourrait être de créer des clés à une seule colonne pour from_ip
et to_ip
. Puisqu'il s'agit d'entiers, il y a de fortes chances que les indices de résultat aient une cardinalité élevée. Cependant, MySQL ne peut utiliser qu'un seul index et, par conséquent, vous perdrez la "moitié" de la comparaison efficace de la plage. N'oubliez pas non plus que si la comparaison supérieure à (ou inférieure à) affecte trop de lignes, MySQL n'utilisez pas index également (puisque, évidemment, cela n'a aucun sens car il y a trop de lignes à sélectionner).
Et - oui, évitez d'utiliser les fonctions dans WHERE
clause. Je ne dis pas que MySQL perdra toujours l'utilisation de l'index dans ce cas (mais très probablement, il le perdra dans la plupart des cas) - mais pensez à la surcharge qui entraînera un appel de fonction. Même si c'est peu - vous pouvez toujours vous en débarrasser en passant la valeur correcte, formée par votre application.