2013-02-12 6 views
0

J'ai deux tables qui ressemblent à ceci:optimisation de schéma Oracle pour 1: 0..1 relation

table A: FieldID NUMBER (PK), other non-relevant fields 
table B: FieldID NUMBER (PK/FK), other non-relevant fields 

Les tables mappées 1: relation 0..1. Spécifiquement, après qu'une nouvelle ligne est insérée dans la table A, à un certain moment dans la future table B sera remplie avec des données supplémentaires.

Cette conception a été à l'origine préférée à une table étendue unique afin d'avoir des champs non nulles partout (car il n'y a aucune possibilité de prédire quand la partie "B" des données sera remplie). Maintenant ... Les performances d'une sélection de jointure de A et B sont étonnamment horribles. Nous parlons de quelques lignes de 100k dans les deux tables, et pourtant une jointure interne simpe prend énormément de temps à compléter. En plus de déplacer les champs de B dans A (chose que je ne préfère pas faire pour éviter les vérifications "nulles" supplémentaires), comment puis-je améliorer mes performances?

+1

Définir "affreux", en particulier est-il pour les requêtes PK simples ou FULL TABLE SCAN? –

+0

Salut, c'est pour une recherche PK. Si je fais (par exemple) sélectionner * de A, B où A.FieldID = B.FieldID et rownum <= 10, cela prend ~ 20 secondes pour terminer. – Andrea

+0

Veuillez poster le plan d'explication. [Tracer la requête] (http://docs.oracle.com/cd/E11882_01/server.112/e16638/sqltrace.htm#PFGRF01020) peut également aider à comprendre pourquoi cela prend autant de temps. –

Répondre

1

Ne vous joindre comme ceci: SELECT /*+GATHER_PLAN_STATISTICS*/ ... FROM .. WHERE ...; Et puis, nous montrent la sortie: SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATS LAST'));

Cela montrera le plan d'exécution avec les statistiques associées, selon les estimations, et effectivement trouvé lors de l'exécution de la requête.

+0

Salut, merci pour votre considération. Je n'ai pas accès à cette fonctionnalité, mais je vais demander à mon dba de me le fournir. – Andrea

+1

Espérons que vous l'aurez. L'accès aux plans d'exécution et ce type d'informations de retour de cardinalité est essentiel pour l'analyse des performances des requêtes. –

+0

@Andrea Dites-lui un gars aléatoire de l'Internet vous a demandé. ;) Plus sérieusement, comme l'a dit @DavidAlridge, c'est essentiel si vous voulez identifier le vrai problème. Ou vous pouvez utiliser 'set autotrace' dans sql * plus, c'est mieux que rien mais vous n'obtenez pas la différence entre les lignes attendues et réelles. – Plouf

1

Si vous combinez les deux tables pour toutes les lignes, vous devez obtenir les meilleures performances d'une jointure de hachage. Si le petit ensemble de données jointes peut être mis en cache, le coût est légèrement supérieur à un balayage complet des deux tables, ce qui est à peu près aussi efficace que possible. Si vous joignez uniquement un petit nombre de lignes, un cluster de hachage peut être utile, car il regroupe physiquement les lignes des deux tables et rend une jointure très efficace pour un petit nombre de lignes. L'inconvénient est qu'un balayage complet de l'un ou l'autre, en particulier la plus petite table, sera plus cher et les insertions seront aussi.