2017-10-17 7 views
0

Je suis sur Oracle 11g et nous avons ces tableaux 3 clés:base de données Oracle aide l'optimisation comme la recherche

Customer - CUSTOMERID|DOB 
CustomerName - CUSTOMERNAMEID|CustomerID|FNAME|LNAME 
Address - ADDRESSID|CUSTOMERID|STREET|CITY|STATE|POSTALCODE 

J'ai environ 60 millions de lignes sur chacune des tables et les données sont un mélange de États-Unis et au Canada population.

J'ai une application frontale qui appelle un service web et qui fait un nom de famille et une recherche partielle. Donc, ma requête a essentiellement

where CUSTOMERNAME.LNAME = ? and ADDRESS.POSTALCODE LIKE '?%' 

Ils fournissent généralement les 3 premiers chiffres de la fermeture éclair.

La table d'adresse a un index sur tous les rue/ville/état/zip et un autre sur l'état et le zip.

J'ai essayé d'ajouter un index exclusivement pour le zip et forcer Oracle à utiliser cet index sur ma requête, mais cela n'a fait aucune différence.

Pour retourner environ 100 lignes (j'ai pagination pour n'en renvoyer que 100 à la fois) cela prend environ 30 secondes, ce qui n'est pas idéal. Que puis-je faire pour améliorer cela?

+0

Vous avez besoin pour montrer votre requête.Je suppose que les tables sont jointes sur CUSTOMERID, donc CUSTOMERID s/b indexé sur chaque table. –

+0

Le problème est que les codes postaux sont tous des chiffres (si vous parlez des États-Unis), mais ils sont stockés en tant que chaînes (pas vraiment un choix dans cela, vraiment). Même avec un index, sans plus d'aide Oracle ne sait pas qu'entre 099 et 100 il n'a pas besoin de chercher 09A et 09W. Donc, ses estimations de cardinalité seront loin. Une façon d'aider Oracle est d'ajouter des histogrammes. https://docs.oracle.com/database/121/TGSQL/tgsql_histo.htm#TGSQL366 – mathguy

+0

Ensuite: LNAME devrait être beaucoup plus sélectif que POSTALCODE, mais vous n'avez pas mentionné d'index sur LNAME. Est-ce qu'il y a un? – mathguy

Répondre

0

Le problème est que les filtres que vous appliquez ne sont pas très sélectifs et qu'ils s'appliquent à différentes tables. C'est mauvais pour un index btree démodé. Si le contenu est très statique, vous pouvez essayer les index bitmap. Plus précisément, un index de jointure basé sur une fonction sur les trois premières lettres du nom de famille et un index de jointure bitmap sur la colonne de code postal. Cela suppose que très peu de personnes dont le nom de famille commence par certaines lettres vivent dans un certain code postal.

CREATE BITMAP INDEX ix_customer_custname ON customer(SUBSTR(cn.lname,1,3)) 
FROM customer c, customername cn 
WHERE c.customerid = cn.customerid; 

CREATE BITMAP INDEX ix_customer_postalcode ON customer(SUBSTR(a.postalcode,1,3)) 
FROM customer c, address a 
WHERE c.customerid = a.customerid; 

Si vous avez réussi, vous devriez voir les deux index bitmap devenir ET connectés. Le temps d'exécution devrait tomber à quelques secondes. Ce ne sera pas aussi rapide qu'un index btree.

Remarques:

  • Vous devrez peut-être jouer un peu s'il est plus efficace de faire un ou deux index et si la fonction sont utiles utiles.

  • Si vous décidez de le faire en fonction de la fonction, vous devez inclure exactement les mêmes appels de fonction dans la clause where de votre requête. Sinon, l'index ne sera pas utilisé.

  • Les opérations DML seront considérablement plus lentes. Ceci n'est utile que pour les tables contenant des données statiques. Notez que les opérations DML bloquent les "plages" de lignes entières. Les opérations DML simultanées rencontreront des problèmes.

  • Le temps de réponse sera probablement encore secondes ne pas instante comme un indice BTREE. AFAIK cela ne fonctionnera que sur l'édition d'entreprise. La syntaxe n'est pas testée car je n'ai pas de base de données d'entreprise disponible pour le moment.

  • Si cela n'est pas encore assez rapide, vous pouvez créer une vue matérialisée avec le nom du client, le nom de famille et le code postal et un index btree. Mais c'est un peu cher, aussi.

+3

Je recommanderais contre un index 'BITMAP' s'il y a un niveau d'écriture simultanée dans les tables. –

+0

Je suis d'accord à 100%. Une fois que vous avez des index bitmap sur votre table, vous n'avez plus de verrouillage de ligne. Exécuter des opérations DML parallèles sur cela demande des problèmes. – fhossfel

+0

Merci. Oui, il y aura une écriture simultanée. Mais l'index BITMAP semble être une bonne idée pour un autre cas d'utilisation que nous avons. – user3726933