Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Devarsh.

Asked: March 03, 2011 - 12:47 am UTC

Last updated: March 04, 2011 - 8:41 am UTC

Version: 11g

Viewed 1000+ times

You Asked

Hi tom,
Can this query be re-written in a better way...

SELECT APSU.VENDOR_ID,
APSU.VENDOR_NAME,
APS.VENDOR_CONTACT_ID CURRENT_VENDOR_CONTACT_ID,
min(VENDOR_CONTACT_ID) over (partition by
PER_PARTY_ID,ORG_PARTY_SITE_ID) NEW_VENDOR_CONTACT_ID,
ASSA.VENDOR_SITE_ID,
ASSA.VENDOR_SITE_CODE,
( select HPS.PARTY_SITE_NAME from hz_party_sites hps where
party_site_id = assa.party_site_id ) party_site_name ,
APS.INACTIVE_DATE,
APS.FIRST_NAME,
APS.MIDDLE_NAME,
APS.LAST_NAME,
APS.PREFIX,
APS.TITLE,
APS.PHONE,
APS.PER_PARTY_ID,
APS.RELATIONSHIP_ID,
APS.REL_PARTY_ID,
APS.ORG_CONTACT_ID,
APS.ORG_PARTY_SITE_ID,
'Y' process_flag
from ap_supplier_contacts aps,
ap_suppliers apsu,
ap_supplier_sites_all assa
where aps.ORG_PARTY_SITE_ID = assa.party_site_id
and assa.vendor_id = apsu.vendor_id
and assa.creation_date between
to_date('&start_date') and to_date('&end_date')
and exists ( select 'x' from
ap_supplier_contacts asuc
where asuc.org_party_site_id = assa.party_site_id
and asuc.per_party_id = aps.per_party_id
group by asuc.per_party_id, org_party_site_id
having count(*) > 1
) ;

The above query was given to me by a friend of mine.. he asked me if I could improve upon it..
Let me know if you need more information.

and Tom said...

read the first part of this article:

http://www.oracle.com/technetwork/issue-archive/2011/11-mar/o21asktom-312223.html

and you'll understand why the only answer one could give is "I don't know"

because

I don't know your schema
I don't know your constraints
I don't know your data volumes
I don't know your indexing strategy
I don't know THE QUESTION you are trying to answer



I see "hz_party_sites" and then have to add

I don't know your views and their definition


I'm just publishing this one to remind people (since this is the 3rd query I've received today alone - this is the smallest one - one was 515 lines long and the other was about 120 lines long) that....


The optimizer is the thing that can take an arbitrary sql statement and compile it.

A human needs all of the information the optimizer would have AND MORE in order to do anything "smarter" than the optimizer already did.


(please don't give me that information here - I'm not typically into tuning individual sql statements for people, not the best use of my time)

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Devarsh: Try using DBMS_SQLTUNE... maybe it can help...

A reader, March 03, 2011 - 8:06 pm UTC

Cheers!!
Tom Kyte
March 04, 2011 - 8:41 am UTC


Thanks Tom

Devarsh, March 03, 2011 - 9:33 pm UTC

Tom..
My apologies for this question.

I have been 'studying' oracle on this site for almost a decade now..
This was the original question that I got from a friend of mine

SELECT APSU.VENDOR_ID,
APSU.VENDOR_NAME,
APS.VENDOR_CONTACT_ID CURRENT_VENDOR_CONTACT_ID,
min(VENDOR_CONTACT_ID) over (partition by
PER_PARTY_ID,ORG_PARTY_SITE_ID) NEW_VENDOR_CONTACT_ID,
ASSA.VENDOR_SITE_ID,
ASSA.VENDOR_SITE_CODE,
HPS.PARTY_SITE_NAME,
APS.INACTIVE_DATE,
APS.FIRST_NAME,
APS.MIDDLE_NAME,
APS.LAST_NAME,
APS.PREFIX,
APS.TITLE,
APS.PHONE,
APS.PER_PARTY_ID,
APS.RELATIONSHIP_ID,
APS.REL_PARTY_ID,
APS.ORG_CONTACT_ID,
APS.ORG_PARTY_SITE_ID,
'Y' process_flag
from ap_supplier_contacts aps,
ap_suppliers apsu,
ap_supplier_sites_all assa,
hz_party_sites hps
where aps.ORG_PARTY_SITE_ID = hps.party_site_id
and assa.party_site_id = hps.party_site_id
and assa.vendor_id = apsu.vendor_id
and hps.party_id = apsu.party_id
and (per_party_id, org_party_site_id) in
(select per_party_id, org_party_site_id
from ap_supplier_contacts asuc
where ORG_PARTY_SITE_ID IN (SELECT DISTINCT PARTY_SITE_ID ROM AP_SUPPLIER_SITES_ALL ASSA2
WHERE ASSA2.creation_date between
to_date('&start_date') and to_date('&end_date'))
group by per_party_id, org_party_site_id
having count(*)>1);

The query was providing data as expected but was taking way much of time..

I re-wrote it as per my initial post..
I am aware of what you had said in your review.. have read this multiple times in your responses to such questions earlier..

I took liberty to post this question with a hope that if you could find a better way just by looking at the query..

Sorry for wasting your time..Thanks

Devarsh....

Tom N, March 07, 2011 - 9:02 am UTC

Outside of anything that Tom already covered, may I also add: Make sure your join columns are actually covered with a Foreign Key constraint... the Oracle optimizer uses those constraint definititions when figuring out how to generate the data set. Also, make sure those Foreign Key columns are indexed... finally, any where clause predicates that do value-comparisons (where x='Y')such as the assa.creation_dt should be considered for indexing, as in this case it may be able to isolate rows faster if Oracle determines table access by index is more efficient than just dumping the whole table into RAM... beyond that, without knowing the things Tom asked about, it's impossible to do much more since this query is mostly just "join these tables and give me these columns"...

More to Explore

Analytics

Analytic SQL got you confused? Check out Connor McDonald's complete video course.