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

Oracle :recherche plein texte avec condition

Texte Oracle

1 - Vous pouvez améliorer les performances en créant l'index CONTEXT avec FILTER BY :

create index my_idx on my_table(text) indextype is ctxsys.context filter by group_id;

Dans mes tests, le filter by certainement amélioré les performances, mais il était encore légèrement plus rapide d'utiliser simplement un index btree sur group_id.

2 - Les index CTXCAT utilisent des "sous-index" et semblent fonctionner comme un index multi-colonnes. Cela semble être l'option (4) que vous recherchez :

begin
  ctx_ddl.create_index_set('my_table_index_set');
  ctx_ddl.add_index('my_table_index_set', 'group_id');
end;
/

create index my_idx2 on my_table(text) indextype is ctxsys.ctxcat
    parameters('index set my_table_index_set');

select * from my_table where catsearch(text, 'blah', 'group_id = 43') > 0

C'est probablement l'approche la plus rapide. L'utilisation de la requête ci-dessus contre 120 Mo de texte aléatoire similaire à votre scénario A et B ne nécessitait que 18 obtentions cohérentes. En revanche, la création de l'index CTXCAT a pris près de 11 minutes et utilisé 1,8 Go d'espace.

(Remarque :Oracle Text semble fonctionner correctement ici, mais je ne connais pas Text et je ne peux pas garantir qu'il ne s'agit pas d'une utilisation inappropriée de ces index, comme l'a dit @NullUserException.)

Index multi-colonnes et jointures d'index

Pour la situation que vous décrivez dans votre modification, normalement il n'y aurait pas de différence significative entre l'utilisation d'un index sur (A, B) et la jointure d'index séparés sur A et B. J'ai construit des tests avec des données similaires à ce que vous avez décrit et une jointure d'index ne nécessitait que 7 obtentions cohérentes contre 2 obtentions cohérentes pour l'index multi-colonnes.

La raison en est qu'Oracle récupère les données dans des blocs. Un bloc est généralement de 8 Ko et un bloc d'index est déjà trié, vous pouvez donc probablement adapter les valeurs 500 à 2000 dans quelques blocs. Si vous vous inquiétez des performances, les E/S pour lire et écrire des blocs sont généralement la seule chose qui compte. Qu'Oracle doive ou non réunir quelques milliers de lignes représente une quantité de temps CPU sans conséquence.

Cependant, cela ne s'applique pas aux index Oracle Text. Vous pouvez joindre un index CONTEXT avec un index btree (un "bitmap et" ?), mais les performances sont médiocres.