C'est probablement une question vraiment stupide, mais y-a-t-il un avantage à indexer un champ booléen dans une table de base de données?
Dans une situation courante, telle que les enregistrements de type "suppression au toucher" marqués comme inactif, la plupart des requêtes incluent donc WHERE deleted = 0
, serait-il utile de l'indexer lui-même ou de le combiner avec les autres champs couramment recherchés un index différent?
Non.
Vous indexez les champs recherchés et qui ont une sélectivité/cardinalité élevée. La cardinalité d'un champ booléen est effacée dans presque toutes les tables. Si quoi que ce soit, cela ralentira vos écritures (d'une quantité infime).
Peut-être en feriez-vous le premier champ de l'index en cluster si chaque requête prenait en compte les suppressions logicielles?
Qu'en est-il d'une colonne delete_at DATETIME? Il y a deux avantages.
Votre requête pourrait ressembler à ceci:
SELECT * FROM xyz WHERE deleted_at IS NULL
Je pense que cela aiderait, en particulier pour couvrir les indices.
Combien/peu dépend naturellement de vos données et requêtes.
Vous pouvez avoir toutes sortes de théories sur les index mais les réponses finales sont données par le moteur de base de données dans une base de données contenant des données réelles. Et souvent, vous êtes surpris par la réponse (ou peut-être que mes théories sont trop mauvaises;)
Examinez le plan de requête de vos requêtes et déterminez si les requêtes peuvent être améliorées ou si les index peuvent être améliorés.
je pense que si votre champ booléen est tel que vous y faites allusion dans de nombreux cas, il serait logique de disposer d'un tableau séparé, par exemple DeletedPages ou SpecialPages, qui contiendra de nombreux champs de type booléen, tels que is_deleted
, is_hidden
, is_really_deleted
, requires_higher_user
etc, et ensuite vous prendriez des jointures pour les obtenir.
En règle générale, la taille de cette table serait plus petite et vous auriez un avantage à prendre des jointures, notamment en ce qui concerne la lisibilité et la maintenabilité du code. Et pour ce type de requête:
select all pages where is_deleted = 1
Ce serait plus rapide de l'avoir implémenté comme ceci:
select all pages where pages
inner join DeletedPages on page.id=deleted_pages.page_id
Je pense avoir lu quelque part au sujet des bases de données mysql qu'il est nécessaire d'avoir un champ d'au moins 3 cardinalités pour que l'indexation fonctionne correctement sur ce champ, mais veuillez le confirmer.
Je pense que cela aiderait si vous utilisiez une vue (où supprimé = 0) et que vous interrogez régulièrement à partir de cette vue.
Si vous utilisez une base de données prenant en charge les index bitmap (tels que Oracle), un tel index sur une colonne booléenne sera beaucoup plus utile que sans.