2011-09-08 4 views
2

J'ai une table qui est fondamentalement une structure arborescente avec une colonne parent_id et id.Oracle: table organisée par index avec des valeurs nulles

parent_id est null pour les nœuds racine.

Il existe également une clé étrangère auto-référentielle, de sorte que chaque parent_id a un id correspondant.

Cette table est principalement en lecture seule avec des mises à jour par lots pour la plupart peu fréquentes.

L'une des requêtes les plus courantes de l'application qui accède à cette table est select ... where parent_id = X. Je pensais que cela pourrait être plus rapide si cette table était indexée sur parent_id.

Cependant, je ne suis pas sûr comment indexer organiser cette table si parent_id peut être null. Je préfère ne pas fudger les choses de sorte que parent_id=0 soit un identifiant spécial, car il faudrait ajouter des valeurs factices à la table pour s'assurer que les contraintes de la clé étrangère sont satisfaites, et cela change aussi la logique de l'application.

Existe-t-il un moyen d'indexer organiser une table par des colonnes de valeur null possibles?

+0

Si j'étais vous je voudrais juste aller avec la valeur 0 dummy. –

+1

En relation: http://stackoverflow.com/questions/1230786/when-does-oracle-index-null-column-values ​​ – NullUserException

Répondre

1

Solution de asker question:

J'ai trouvé que je pouvais obtenir les mêmes avantages de l'organisation d'index en ajoutant simplement les colonnes interrogées à la fin de l'indice parent_id, soit au lieu de:

create index foo_idx on foo_tab(parent_id); 

je:

create index foo_idx on foo_tab(parent_id, col1, col2, col3); 

col1, col2, col3 etc sont des colonnes fréquemment consultées.

Je l'ai seulement fait avec des index qui sont utilisés pour retourner plusieurs lignes qui bénéficient de la commande et donc de la localité de disque fournie par l'index, au lieu de devoir sauter autour de la table. Les index qui sont généralement utilisés pour renvoyer des lignes simples que j'ai laissées pour référencer la table, car il n'y a qu'une seule ligne à lire, donc la localité importe beaucoup moins.Comme je l'ai mentionné, il s'agit principalement d'une table lue, et l'espace n'est pas un gros problème, donc je ne pense pas que le surcoût d'écriture provoqué par ces index soit un gros problème.

(Je sais que cela ne indexera nullparent_id s, mais je l'ai fait un autre indice sur decode(parent_id, null, 1, null) qui indexe les valeurs nulles et seulement nulls).

+0

+1 pour l'indexation d'autres colonnes, mais votre index sur le décodage (parent_id, null, 1, null) ne fonctionnera pas comme prévu. cette expression renvoie toujours null. –

+0

@Florin: Merci, mais ne sélectionne pas décoder (null, null, 1, null) à partir de dual; 'return 1? – Clinton

+0

wow, vous avez raison! renvoie 1 ... Je suis stupéfait. Je savais que null n'est pas nul. probablement décoder est un cas particulier. Mes excuses. –

0

Je voudrais essayer d'ajouter l'index sur la seule colonne parent_id.

Si toutes les colonnes de votre index sont non nulles, cette ligne n'apparaît pas dans votre index.

Donc pour le parent_id = X vous citez ci-dessus, cela devrait utiliser l'index. Cependant, si vous faites parent_id is null, alors il n'utilisera pas l'index, et vous obtiendrez les mêmes performances que vous avez maintenant. Cela ressemble à un comportement qui vous conviendrait. J'ai déjà utilisé cela dans le passé pour améliorer les performances des requêtes. Cela fonctionne particulièrement bien si le nombre d'éléments dans l'index est petit par rapport au nombre de lignes dans la base de données. Nous avions environ 3% de nos lignes dans cet index particulier, et il a volé :-)

Mais, comme toujours, vous devez l'essayer et mesurer la différence de performance. Votre kilométrage peut varier.

Questions connexes