2009-07-28 7 views
22

Est-ce queSub ou LIKE est-il plus rapide dans Oracle?

WHERE substr(my_field,1,6) = 'search' 

ou

WHERE my_field LIKE 'search%' 

plus rapide dans Oracle, ou aurait-il pas de différence?

+0

Voir aussi http://stackoverflow.com/questions/8646623/what-is-the-difference-between-instr-and-like-in-oracle – Vadzim

Répondre

19

En supposant que la performance maximale est l'objectif, je choisirais idéalement SUBSTR(my_field,1,6) et créer un index basé sur la fonction pour soutenir la requête.

CREATE INDEX my_substr_idx 
    ON my_table(substr(my_field,1,6)); 

Comme d'autres font remarquer, SUBSTR(my_field,1,6) ne serait pas en mesure d'utiliser un index régulier sur MY_FIELD. La version LIKE peut utiliser l'index, mais les estimations de la cardinalité de l'optimiseur dans ce cas sont généralement médiocres. Il est donc fort probable que l'index ne soit pas utile ou que l'index soit préférable. L'indexation de l'expression réelle donnera à l'optimiseur beaucoup plus d'informations à utiliser, donc il est beaucoup plus probable de choisir l'index correctement. Quelqu'un de plus intelligent que moi peut être en mesure de suggérer un moyen d'utiliser les statistiques sur les colonnes virtuelles dans 11g pour donner à l'optimiseur de meilleures informations pour la requête LIKE. Si 6 est une variable (c'est-à-dire que vous voulez parfois rechercher les 6 premiers caractères et parfois rechercher un nombre différent), vous ne pourrez probablement pas trouver d'index basé sur les fonctions pour prendre en charge cette requête . Dans ce cas, vous êtes probablement mieux avec les caprices des décisions de l'optimiseur avec la formulation LIKE.

9

Parmi les deux options fournies, certainement comme. La méthode de sous-chaîne devra être exécutée sur toutes les lignes de la table. L'utilisation de LIKE permettra l'utilisation d'index.

Pour vérifier ma réponse, il suffit de profiler les résultats. Cela devrait être clair comme le jour.

+0

LIKE est peut-être plus rapide, certainement pas. Même s'il existe un index, il peut ou non être utilisé en fonction de la sélectivité. –

+0

@Alex - Vrai. Mais dans tous les cas, il vaut mieux essayer le meilleur et permettre au serveur l'option d'utiliser des index si disponibles. L'utilisation de la méthode de sous-chaîne garantit qu'aucun index ne sera utilisé. – beach

+5

D'accord. Mais vous pouvez frapper un index basé sur une fonction sur SUBSTR (my_field, 1,6) qui serait plus susceptible d'être utilisé qu'un index normal sur my_field pour le LIKE. –

2

Si vous avez un index sur my_field, alors LIKE peut être plus rapide. Faites vos propres repères.

0

Je voudrais profiler les deux. Mais je suppose que le 'LIKE' serait beaucoup plus rapide, car il utilise la recherche binaire sur l'index (si le champ est indexé). Si vous utilisez la méthode SUBSTR, vous obtiendrez une analyse de table complète, Oracle devant traiter la fonction ligne par ligne.

1

Il y a vraiment deux questions:

  1. Pour que l'on va produire Oracle la cardinalité plus précis et une estimation des coûts?
  2. Quelle méthode est la plus flexible en termes de méthodes d'accès potentiel?

Cela peut varier selon la version, mais les deux sont assez faciles à tester et vous êtes ainsi certain d'avoir les meilleures informations pour votre version et vos données.

plans d'exécution d'exécution pour les requêtes à l'aide ...

explain plan for 
select ... from ... where my_field LIKE 'search%'; 

select * from table(dbms_xplan.display); 

et

explain plan for 
select ... from ... where substr(my_field,1,6) = 'search'; 

select * from table(dbms_xplan.display); 

Vous pouvez voir une différence dans le plan d'exécution, en fonction de la présence d'index, etc., Mais aussi de comparer les estimations de cardinalité avec le résultat réel que vous obtenez de:

select count(*) from ... where my_field LIKE 'search%'; 

L'une des deux méthodes peuvent être beaucoup plus précis que l'autre.

Si aucun d'entre eux est très précis et cette requête devrait fonctionner pendant un laps de temps non négligeable alors envisager d'utiliser l'échantillonnage dynamique pour améliorer l'estimation, car avec la mauvaise cardinalité estimation de l'optimiseur peut choisir un suboptimale méthode d'accès de toute façon.

explain plan for 
select /*+ dynamic_sampling(4) */ ... from ... where substr(my_field,1,6) = 'search'; 

select * from table(dbms_xplan.display); 

En ce qui concerne l'utilisation de l'index, les deux méthodes peuvent utiliser une méthode d'accès basée sur l'index. Le prédicat LIKE est probablement plus convivial pour les index et peut utiliser une analyse de plage ou un balayage rapide d'index complet. La méthode SUBSTR peut certainement utiliser l'analyse rapide de l'index complet, mais si l'optimiseur considère qu'une analyse de distance est mieux testée sur votre propre version - je me rappelle qu'elle ne le sera pas mais qui doit dire substr (my_column, , n) ne sera pas reconnu comme un cas particulier, sinon maintenant, dans le futur?

2

Si vous avez pas d'index qu'il n'y a pas de différence. Parce que Oracle effectue une analyse de table complète et évalue l'expression de chaque ligne. Vous pouvez placer un index sur la colonne pour accélérer les deux requêtes.

CREATE INDEX my_like_idx 
ON my_table(my_field); 

Cet index est plus flexible et accélère la requête en utilisant comme. Cela fonctionnera pour n'importe quelle comparaison commençant par des caractères et ayant l'espace réservé (%) à la fin. Oracle effectue une analyse de plage d'index pour rechercher toutes les lignes correspondantes.

CREATE INDEX my_substr_idx 
ON my_table(substr(my_field,1,6)); 

Cet index accélère la requête avec substr. Mais l'index est très spécial pour ne comparer que les 6 premiers caractères.

Si vous recherchez un point de départ au milieu. Créer un index basé sur la fonction aidera.

WHERE substr(my_field,2,5) = 'earch' 
WHERE my_field like '%earch%' 
+0

http://stackoverflow.com/a/30781872/603516 – Vadzim

Questions connexes