2008-09-19 8 views
4

Est-ce que quelqu'un sait pourquoi dans Oracle 11g quand vous faites un Count (1) avec plus d'une jointure naturelle, il fait une jointure cartésienne et jette le compte à rebours?Oracle Natural joint et compte (1)

Tels que

SELECT Count(1) FROM record NATURAL join address NATURAL join person WHERE status=1 
AND code = 1 AND state = 'TN' 

Cela recule comme 3 millions de lignes lorsque

SELECT * FROM record NATURAL join address NATURAL join person WHERE status=1 
AND code = 1 AND state = 'TN' 

tire en arrière comme 36000 lignes, ce qui est le montant exact.

Est-ce que je manque quelque chose?

Voici les tableaux que j'utilise pour obtenir ce résultat.

CREATE TABLE addresses (
address_id   NUMBER(10,0) NOT NULL, 
address_1   VARCHAR2(60) NULL, 
address_2   VARCHAR2(60) NULL, 
city     VARCHAR2(35) NULL, 
state    CHAR(2)  NULL, 
zip     VARCHAR2(5) NULL, 
zip_4    VARCHAR2(4) NULL, 
county    VARCHAR2(35) NULL, 
phone    VARCHAR2(11) NULL, 
fax     VARCHAR2(11) NULL, 
origin_network  NUMBER(3,0) NOT NULL, 
owner_network  NUMBER(3,0) NOT NULL, 
corrected_address_id NUMBER(10,0) NULL, 
"HASH"     VARCHAR2(200) NULL 
); 

CREATE TABLE rates (
rate_id  NUMBER(10,0) NOT NULL, 
eob   VARCHAR2(30) NOT NULL, 
network_code NUMBER(3,0) NOT NULL, 
product_code VARCHAR2(2) NOT NULL, 
rate_type NUMBER(1,0) NOT NULL 
); 

CREATE TABLE records (
pk_unique_id  NUMBER(10,0) NOT NULL, 
rate_id   NUMBER(10,0) NOT NULL, 
address_id  NUMBER(10,0) NOT NULL, 
effective_date DATE   NOT NULL, 
term_date   DATE   NULL, 
last_update  DATE   NULL, 
status   CHAR(1)  NOT NULL, 
network_unique_id VARCHAR2(20) NULL, 
rate_id_2   NUMBER(10,0) NULL, 
contracted_by  VARCHAR2(50) NULL, 
contract_version VARCHAR2(5) NULL, 
bill_address_id NUMBER(10,0) NULL 
); 

Je devrais mentionner que ce n'était pas un problème dans Oracle 9i, mais quand nous sommes passés à 11g, c'est devenu un problème.

+0

Décrivez ces tables. Obtenez-vous les mêmes résultats si vous spécifiez explicitement la jointure interne? – Apocalisp

Répondre

9

Mon conseil serait de ne pas utiliser NATURAL JOIN. Définissez explicitement vos conditions de jointure pour éviter toute confusion et "bugs cachés". Voici les official NATURAL JOIN Oracle documentation et more discussion à ce sujet.

+0

Merci beaucoup! Cela m'a aidé à diagnostiquer mon bug (http://gist.github.com/72614) qui s'est avéré être dû à NATURAL JOINs. – rampion

1

Si cela se produit exactement comme vous le dites, alors doit être être un bug optimiseur, vous devez le signaler à Oracle.

1

vous devriez essayer un compte (*)

Il y a une différence entre les deux.
count (1) signifie des lignes de comptage où 1 est pas compté nul
(*) signifie compter les lignes

+1

Puisque 1 n'est jamais nul, il n'y a pas de différence dans les résultats potentiels. –

+2

... et compte (1) est réécrit pour compter (*) de toute façon. http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1156159920245 –

1

remarqué que vous avez utilisé seulement 2 jointures naturelles ... De la documentation que vous ne pouvez utiliser une jointure naturelle 2 tables Natural_Join

+0

C'est incorrect (et le site que vous avez référencé n'est pas la documentation, c'est un wiki indépendant): Voir http://68.142.116.68/docs/cd/B19306_01/server.102/b14200/statements_10002.htm#sthref9834 –