Bad Performance of Merge Join
We are on ASE 15.0.3/EBF 21284 ESD#4.3 working on a application with over 3000 stored procedures.
Our server optimization goal is allrows_mix.
The Merge-Join is giving us problems. When a query uses Merge-Join, it usually take an order of magnitude longer to run than if we force it
to use the other types of joins - nested-loop, n-ary-nested-loop, or hash-join.
The query plan shows sorting on worktables leading into the merge-join.
I know I can disable it with "set merge_join off", or "set plan optgoal allrows_oltp", but I'd rather not if I can fix the problem instead.
Question: Are there configuration options that would help merge-join?
I've done variations of this:
sp_configure "number of sort buffers", 32000
I've also done variations of this in the proc:
set parallel_degree 5
set scan_parallel_degree 4
When I run the following command, I see sort buffer starvation:
1> sp_monitorconfig "sort buffers"
2> go
Usage information at date and time: Apr 24 2014 2:31PM.
Name Num_free Num_active Pct_act Max_Used Reuse_cnt
number of sort buffers 0 82045 100.00 82045 0
(1 row affected)
(return status = 0)
Maybe there are other configuration option to help merge-joins? Any ideas?
Thanks.
Well, I'm gonna have to emphatically disagree with your comment ...
"regressing back to allrows_oltp setting to solve your performance problems should not be encouraged"
For *EVERY* client I've worked with on migrating from ASE 12.5.x to ASE 15.x ... they all had the same objective ... get through the migration as quickly as possible and do not degrade the performance of our database queries. Unfortunately for every client I've worked with ... ASE 15.x, and the default of allrows_mix, did just the opposite, ie, migrations took much longer than expected/planned due primarily to huge performance degradation across their SQL inventory.
For most of my clients merge joins were rarely, if ever, used in ASE 12.5.x. And since hash joins never existed, that leaves us with using nested loop joins in ASE 15.x in an attempt to stay as close to ASE 12.5.x in terms of performance.
NOTE: No, I don't consider compatibility mode as a solution as this requires you go through 2 migrations ... once to compatibility mode ... and eventually once to get off of compatibility mode.
Now, can merge joins improve the performance of *some* queries? Absolutely, but in practice ... especially with the first 4-5 years of ASE 15.x releases ... merge joins caused more headaches and performance degradation than they were worth. I've seen too many clients spend huge amounts of time trying to re-write code to work with merge joins, often failing and having to 'regress back' to nested loop joins in the end.
Unfortunately a) Sybase delivered ASE 15.x with allows_mix as the default and b) most companies didn't have enough migration experience to understand the pitfalls of trying to run all of their queries under the default of allrows_mix. This meant that many companies were left having to 'regress back' to alternative solutions (eg, allrows_oltp, compat mode, don't migrate, move to another RDBMS) to address the performance degradation introduced with ASE 15.x and the default setting of allrows_mix.
Similar Messages
-
Merge Join Cartesian performing bad on 10g
Hello All,
I have a merge join cartesian query that took seconds in 8i. Once the database was upgraded to 10g, the same query is taking hours. In looking at the explain plans, it looks like the access paths are identical.
Has anyone encountered this issue?
Thanks.Sometimes the cost-based optimizer will do cartesian joins to optimize a query. Seeing the word "cartesian" in a query plan is still a major red flag to my eyes. Also, performance changes between versions are usually expected, though most people complain about 9i to 10g results these days :)
Are you sure you need to be doing a cartesian join at all? As Fly pointed out they have a bad reputation, and yours must be running badly as per your post. I personally get more efficient results from hash joins over sort merges these days so that's something you can look at.
Try variations on your query to generate execution plans to see if you can get better results. Don't forget to actually time results since plan statistics have been known to be out-of-touch with actual run performance.
Good luck! -
we have two views with equal key fields which perform very good (order less than 1 second).
Both views give extra fields from data sets.
I want to combine those extra fields in one record with equal key values. Because some key combinations can miss in either one of both sets, I make an extra view with a union only on the keyfields of both views and use this view as driver for the combination, so I join both original views open with this driver. When I now query the resultview the performance is bad (order 3.5 minutes).
(This is independent of the number of result records)
Explain plan shows no full table scans.
Any suggestions to improve this construction??I have split the two parts of the union query, and analysed both parts separately, see below.
The subviews perform as follows:
c_contr_opb_CD with restriction on contract_no 7 rows in 0:02 seconds
without restrictions 2216 records in 3:34 minutes
c_contr_opb_B with restriction on contract_no 5 rows in 0:01 seconds
without restrictions 1567 records in 0:05 minutes
(in both views are 1332 records with common keys)
When I make the view over an open join of both views and I use the
c_contr_opb_B as driver then it performs with and without restriction
on contract_no the same, suggesting it performs the 'group by'-clause in
the view c_contr_opb_CD before applying the restriction.
When, on the other hand I use the view c_contr_opb_CD as driver it seems to
apply the restriction before the 'group by'-clause in the view.
Is there a way to always apply the restriction berore the 'group by' clause
select tB.Contract_no
, tB.agc
, tB.salesgroup
, tB.B_pricing
, tB.B_No_of_elements
, tB.B_m3_elements
, tB.C_complete
, tCD.C_pricing
, tCD.C_No_of_elements
, tCD.C_m3_elements
, tCD.D_pricing
, tCD.D_No_of_elements
, tCD.D_m3_elements
from c_contr_opb_CD tCD
, c_contr_opb_B tB
where (tCD.Contract_no(+) = tB.Contract_no
and tCD.agc(+) = tB.agc
and tCD.salesgroup(+) = tB.salesgroup)
and tB.contract_no=lpad('20042002',20);
query in 3:40 minutes, result 5 records
Options Object Operation
SELECT STATEMENT
OUTER MERGE JOIN
JOIN SORT
C_CONTR_OPB_B VIEW
GROUP BY SORT
VIEW
UNION-ALL
NESTED LOOPS
UNIQUE SCAN PK_CMHD INDEX
BY INDEX ROWID CMMT TABLE ACCESS
RANGE SCAN PK_CMMT INDEX
NESTED LOOPS
UNIQUE SCAN PK_CMHD INDEX
BY INDEX ROWID CMSV TABLE ACCESS
RANGE SCAN PK_CMSV INDEX
JOIN SORT
C_CONTR_OPB_CD VIEW
GROUP BY SORT
VIEW
UNION-ALL
NESTED LOOPS
RANGE SCAN X_SHP_CM INDEX
BY INDEX ROWID CMMT TABLE ACCESS
RANGE SCAN PK_CMMT INDEX
NESTED LOOPS
RANGE SCAN X_SHP_CM INDEX
BY INDEX ROWID CMSV TABLE ACCESS
RANGE SCAN PK_CMSV INDEX
28 rows selected.
select tCD.Contract_no
, tCD.agc
, tCD.salesgroup
, tB.B_pricing
, tB.B_No_of_elements
, tB.B_m3_elements
, tB.C_complete
, tCD.C_pricing
, tCD.C_No_of_elements
, tCD.C_m3_elements
, tCD.D_pricing
, tCD.D_No_of_elements
, tCD.D_m3_elements
from c_contr_opb_B tB
, c_contr_opb_CD tCD
where (tB.Contract_no(+) = tCD.Contract_no
and tB.agc(+) = tCD.agc
and tB.salesgroup(+) = tCD.salesgroup)
and tCD.contract_no=lpad('20042002',20);
query in 0:05 minutes, result 7 rows
Options Object Operation
SELECT STATEMENT
OUTER MERGE JOIN
JOIN SORT
C_CONTR_OPB_CD VIEW
GROUP BY SORT
VIEW
UNION-ALL
NESTED LOOPS
UNIQUE SCAN PK_CMHD INDEX
BY INDEX ROWID CMMT TABLE ACCESS
RANGE SCAN PK_CMMT INDEX
NESTED LOOPS
UNIQUE SCAN PK_CMHD INDEX
BY INDEX ROWID CMSV TABLE ACCESS
RANGE SCAN PK_CMSV INDEX
JOIN SORT
C_CONTR_OPB_B VIEW
GROUP BY SORT
VIEW
UNION-ALL
NESTED LOOPS
RANGE SCAN X_SHP_CM INDEX
BY INDEX ROWID CMMT TABLE ACCESS
RANGE SCAN PK_CMMT INDEX
NESTED LOOPS
RANGE SCAN X_SHP_CM INDEX
BY INDEX ROWID CMSV TABLE ACCESS
RANGE SCAN PK_CMSV INDEX
create or replace view c_contr_opb_B as
select Contract_no
, agc
, salesgroup
, min(C_complete) C_complete
, sum(B_pricing) B_pricing
, sum(B_No_of_elements) B_No_of_elements
, sum(B_m3_elements) B_m3_elements
from ( select h.cm_num Contract_no
, ms.agc
, ms.sales_group salesgroup
, decode(ms.closed_reason,'C001','*',' ') C_complete
, ms.unit_price*ms.ord_qty B_pricing
, decode(ms.agc,'PROJ',fnc_struct_m3(ms.ccn,ms.structure_id,ms.structure_rev)
,0)*ms.ord_qty B_m3_elements
, ms.ord_qty B_No_of_elements
from cmmt ms
, cmhd h
where ms.ccn = h.ccn
and ms.cm_num = h.cm_num
and ms.price_bucket = 'B'
and ms.closed_reason in ('C001',' ')
and h.ccn = 'SPAN'
UNION ALL
select h.cm_num Contract_no
, ms.agc
, ms.sales_group salesgroup
, decode(ms.closed_reason,'C001','*',' ') C_complete
, ms.unit_price*ms.ord_qty B_pricing
, 0 B_m3_elememts
, ms.ord_qty B_No_of_elements
from cmsv ms
, cmhd h
where ms.ccn = h.ccn
and ms.cm_num = h.cm_num
and ms.price_bucket = 'B'
and ms.closed_reason in ('C001',' ')
and h.ccn = 'SPAN'
) group by Contract_no
, agc
, salesgroup
create or replace view c_contr_opb_CD as
select Contract_no
, agc
, salesgroup
, sum(C_pricing) C_pricing
, sum(C_No_of_elements) C_No_of_elements
, sum(C_m3_elements) C_m3_elements
, sum(D_pricing) D_pricing
, sum(D_No_of_elements) D_No_of_elements
, sum(D_m3_elements) D_m3_elements
from ( select h.cm_num Contract_no
, ms.agc
, ms.sales_group salesgroup
, ms.unit_price*ms.ord_qty C_pricing
, ms.ord_qty C_No_of_elements
, decode(ms.agc,'PROJ',fnc_item_m3(ms.ccn,ms.item,ms.revision),0)
*ms.ord_qty C_m3_elements
, ms.unit_price*ms.ord_qty D_pricing
, decode(ms.agc,'PROJ',fnc_item_aantal_D(ms.ccn,ms.item,ms.revision),0)
D_No_of_elements
, decode(ms.agc,'PROJ',fnc_item_m3_D(ms.ccn,ms.item,ms.revision),0)
* decode(ms.agc,'PROJ',fnc_item_aantal_D(ms.ccn,ms.item,ms.revision),0)
D_m3_elements
from cmmt ms
, cmhd h
where ms.ccn = h.ccn
and ms.cm_num = h.cm_num
and ms.price_bucket = 'C'
and ms.closed_reason in ('F001','F003',' ')
and h.ccn = 'SPAN'
UNION ALL
select h.cm_num Contract_no
, ms.agc
, ms.sales_group salesgroup
, ms.unit_price*ms.ord_qty C_pricing
, ms.ord_qty C_No_of_elements
, 0 C_m3_elememts
, ms.unit_price*ms.ord_qty D_pricing
, 0 D_No_of_elements
, 0 D_m3_elements
from cmsv ms
, cmhd h
where ms.ccn = h.ccn
and ms.cm_num = h.cm_num
and ms.price_bucket = 'C'
and ms.closed_reason in ('F001','F003',' ')
and h.ccn = 'SPAN'
) group by Contract_no
, agc
, salesgroup -
Hi,
I have a query which is using MERGE JOIN CARTESIAN (see step 4 and 11 in execution plan bellow) and i believe this is the culprit and query is never returning. Stats are up to date on all tables. This query involves two remote databases which are accessed using VIEWs from local database. Is there any hint which i can use here to avoid merge join Cartesian and test. Thanks. Also pasting query if any one can have any idea.
Select distinct
substr(Revenue.FKDAT,5,2) || '/' || substr(Revenue.FKDAT,7,2) || '/' || substr(Revenue.FKDAT,1,4) INVOICE_DATE
, Revenue.VBELN INVOICE_NR
, Revenue.ARKTX CUSTDEVICE
, (case Revenue.ZU_LOTID
when null then hstg_partinfo_cust_dw.CUSTPARTOUT
when '' then hstg_partinfo_cust_dw.CUSTPARTOUT
Else
(case decode(trim(zodss1b2.biztype),'TNR-E330-BAKE','TNR','')
when 'TNR' then
(case when (select CUSTPARTOUT from hstg_partinfo_cust_dw Where lotid = 'U' || substr(Revenue.ZU_LOTID,2,7) || '.' || substr(Revenue.ZU_LOTID,9) and stage = 'T998-TFIN' and rownum = 1)
is null then (select CUSTPARTOUT from hstg_partinfo_cust_dw Where lotid = (select parentid from hstg_partinfo_cust_dw where lotid = 'U' || substr(Revenue.ZU_LOTID,2,7) || '.' || substr(Revenue.ZU_LOTID,9) and stage = 'E330-BAKE' and rownum = 1) and stage = 'T998-TFIN' and rownum = 1)
else (select CUSTPARTOUT from hstg_partinfo_cust_dw Where lotid = 'U' || substr(Revenue.ZU_LOTID,2,7) || '.' || substr(Revenue.ZU_LOTID,9) and stage = 'T998-TFIN' and rownum = 1)
end)
else hstg_partinfo_cust_dw.CUSTPARTOUT
end)
end) CUSTPARTOUT
, Revenue.PONUM DO_NR
, Revenue.BSTKD PO_NR
, Revenue.FKIMG GD_QTY
, Revenue.zkbetr GD_PRICE
, Revenue.NETWR GD_AMT
, '' REJ_QTY
, '' REJ_PRICE
, '' REJ_AMT
, Revenue.ZU_LOTID LOTTYPE
,(case Revenue.ZU_LOTID
when null then substr(Revenue.ZU_PRTID,1,instr(Revenue.ZU_PRTID,'.') -1)
when '' then substr(Revenue.ZU_PRTID,1,instr(Revenue.ZU_PRTID,'.') -1)
Else
(case decode(trim(zodss1b2.biztype),'TNR-E330-BAKE','TNR','')
when 'TNR' then
(case when (select substr(PARTID,1,instr(PARTID,'.') -1) from hstg_partinfo_cust_dw Where lotid = 'U' || substr(Revenue.ZU_LOTID,2,7) || '.' || substr(Revenue.ZU_LOTID,9) and stage = 'T998-TFIN' and rownum = 1)
is null then (select substr(PARTID,1,instr(PARTID,'.') -1) from hstg_partinfo_cust_dw Where lotid = (select parentid from hstg_partinfo_cust_dw where lotid = 'U' || substr(Revenue.ZU_LOTID,2,7) || '.' || substr(Revenue.ZU_LOTID,9) and stage = 'E330-BAKE' and rownum = 1) and stage = 'T998-TFIN' and rownum = 1)
else (select substr(PARTID,1,instr(PARTID,'.') -1) from hstg_partinfo_cust_dw Where lotid = 'U' || substr(Revenue.ZU_LOTID,2,7) || '.' || substr(Revenue.ZU_LOTID,9) and stage = 'T998-TFIN' and rownum = 1)
end)
else substr(Revenue.ZU_PRTID,1,instr(Revenue.ZU_PRTID,'.') -1)
end)
end) PARTID
, '' TESTER
, substr(zodss1b2.BSTDK,5,2) || '/' || substr(zodss1b2.BSTDK,7,2) || '/' || substr(zodss1b2.BSTDK,1,4) DO_DATE
, hstg_partinfo_cust_dw.package package
, hstg_partinfo_cust_dw.pincount pincount
, (select c.catg07 from ops$ods_adm.catg c where c.partid=revenue.zu_prtid) as package_size
, (select c.catg09 from ops$ods_adm.catg c where c.partid=revenue.zu_prtid) as wafer_size
, decode(trim(zodss1b2.biztype),'TNR-E330-BAKE','TNR','') BIZTYPE
--from revenue, zodss1b2,dim_partinfo
from revenue, zodss1b2,hstg_partinfo_cust_dw
where Revenue.Remarks <> 'CANCELLED'
and Revenue.FKART in ('ZUF2')
and Revenue.KUNNR in ('BC1001','BC1002','BC1003')
and Revenue.FKDAT like '201008%'
and Revenue.FKIMG > 0
and Revenue.kpein > 0
and Revenue.ZU_LOTID = zodss1b2.charg
and Revenue.MATNR = zodss1b2.matnr
--and Revenue.ZU_PRTID = dim_partinfo.partid
and hstg_partinfo_cust_dw.lotid='U' || substr(Revenue.ZU_LOTID,2,7) || '.' || substr(Revenue.ZU_LOTID,9)
Union all
Select distinct
substr(Revenue.FKDAT,5,2) || '/' || substr(Revenue.FKDAT,7,2) || '/' || substr(Revenue.FKDAT,1,4) INVOICE_DATE
, Revenue.VBELN INVOICE_NR
, Revenue.ARKTX CUSTDEVICE
, hstg_partinfo_cust_dw.CUSTPARTOUT CUSTPARTOUT
, Revenue.PONUM DO_NR
, Revenue.BSTKD PO_NR
, Revenue.FKIMG GD_QTY
, Revenue.zkbetr GD_PRICE
, Revenue.NETWR GD_AMT
, '' REJ_QTY
, '' REJ_PRICE
, '' REJ_AMT
, Revenue.ZU_LOTID LOTTYPE
, substr(Revenue.ZU_PRTID,1,instr(Revenue.ZU_PRTID,'.') -1) PARTID
, '' TESTER
, substr(zodsscrap.BSTDK,5,2) || '/' || substr(zodsscrap.BSTDK,7,2) || '/' || substr(zodsscrap.BSTDK,1,4) DO_DATE
, hstg_partinfo_cust_dw.package package
, hstg_partinfo_cust_dw.pincount pincount
, (select c.catg07 from ops$ods_adm.catg c where c.partid=revenue.zu_prtid) as package_size
, (select c.catg09 from ops$ods_adm.catg c where c.partid=revenue.zu_prtid) as wafer_size
--from revenue, zodsscrap,dim_partinfo
from revenue, zodsscrap,hstg_partinfo_cust_dw
where Revenue.Remarks <> 'CANCELLED'
and Revenue.FKART in ('ZUF2')
and Revenue.KUNNR in ('BC1001','BC1002','BC1003')
and Revenue.FKDAT like '201008%'
and Revenue.FKIMG > 0
and Revenue.kpein > 0
and Revenue.ZU_LOTID = zodsscrap.charg
--and Revenue.ZU_PRTID = dim_partinfo.partid
and hstg_partinfo_cust_dw.lotid='U' || substr(Revenue.ZU_LOTID,2,7) || '.' || substr(Revenue.ZU_LOTID,9);hstg_partinfo_cust_dw is a view which is on remote database USGDWDBP and is queried using synonym in the local database.
revenue is also a view which is in another remote database which is queried using synonym in local database.
ODS Plan
| Id | Operation | Name | Rows | Bytes | Cost | Inst |IN-OUT|
| 0 | SELECT STATEMENT | | 2 | 8532 | 999 | | |
| 1 | UNION-ALL | | | | | | |
| 2 | SORT UNIQUE | | 1 | 4277 | 985 | | |
| 3 | NESTED LOOPS | | 1 | 4277 | 983 | | |
| 4 | MERGE JOIN CARTESIAN| | 1 | 4107 | 980 | | |
| 5 | REMOTE | | 1 | 4076 | 2 | USGDW~ | R->S |
| 6 | BUFFER SORT | | 918K| 27M| 978 | | |
| 7 | TABLE ACCESS FULL | ZODSS1B2 | 918K| 27M| 978 | | |
| 8 | REMOTE | | 1 | 170 | 3 | SAPP0~ | R->S |
| 9 | SORT UNIQUE | | 1 | 4255 | 14 | | |
| 10 | NESTED LOOPS | | 1 | 4255 | 12 | | |
| 11 | MERGE JOIN CARTESIAN| | 1 | 4096 | 9 | | |
| 12 | REMOTE | | 1 | 4076 | 2 | USGDW~ | R->S |
| 13 | BUFFER SORT | | 1755 | 35100 | 7 | | |
| 14 | TABLE ACCESS FULL | ZODSSCRAP | 1755 | 35100 | 7 | | |
| 15 | REMOTE | | 1 | 159 | 3 | SAPP0~ | R->S |
---------------------------------------------------------------------------------------Thanks in advance
SalmanDear Salman Qureshi,
First of all please see Jonathan Lewis' post about the merge join cartesian;
http://jonathanlewis.wordpress.com/2006/12/13/cartesian-merge-join/
You may also check the Thomas Kyte's thread;
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4105951726381
You merge join cartesian cost is so low that the impact will not be that high.
Yes, there are ways to avoid the merge join cartesian. First you have to check the where conditions. Merge join cartesian steps are happening because of the bad SQL algorithm OR sometimes Oracle needs to have a merge join cartesian. At the end, it is up to your SQL.
After than that, you can also use the ORDERED CBO hint to avoid the merge join cartesian.
Please add below line after the SELECT clause and see the new execution plan;
/*+ ORDERED */I hope your problem will be fixed when you show the CBO to use the ORDERED Oracle hint.
About the ORDERED Oracle hint, please check it out;
http://download.oracle.com/docs/cd/B14117_01/server.101/b10752/hintsref.htm#5555
ORDERED
The ORDERED hint causes Oracle to join tables in the order in which they appear in the FROM clause.
If you omit the ORDERED hint from a SQL statement performing a join, then the optimizer chooses the order in which to join the tables. You might want to use the ORDERED hint to specify a join order if you know something about the number of rows selected from each table that the optimizer does not. Such information lets you choose an inner and outer table better than the optimizer could.Hope That Helps.
Ogan -
Reporting on master data customer and bad performances : any workaround ?
Hello,
I've been asked to investiguate on bad performances encountered when performing reporting
on the specific master data zcustomer.
Basically this master data has a quite similar design that 0customer, there are 96000 entries in the master data table.
A simple query has been developed : the reporting is done on the master data zcustomer and its attributes : no key figure, no calculation, no restriction ...
Nevertheless, the query can not be executed .. the query runs around 10 minute in rsrt, then the private memory is exhausted and then a short dump is generated.
I tried to buid a very simple query on 0customer, this time, without the attributes ... and it took more than 30 sec before I get the results.
I checked the queries statistics :
3.x Analyzer Server 10 sec
OLAP: Read Texts : 20 sec
How is it that it is so long to performthe reporitng on those master data, while in the same time If i try to display the content in SAP by choosing "maintain master data", I have an immediate answer.
I there any workaround ?
Any help would be really appreciated.
thank you.
RaoulHi.
How much data have you got in the cube?
If you make no restrictions, you are asking the system to return data for all 96.000 customers. That is one thing that might take some time.
Also, using the attributes of this customer object, fx making selection or displaying several of them, means that the system has to run through the 96.000 records in masterdata to know what goes where in the report.
When you display the masterdata, you are by default displaying just the 250 or so first hits, and you are not joining against any cube or sorting the result set, so that is fast.
You should make some kind of restriction on other things than zcustomer (time, org.unit, version, etc, to limit the dataset from the cube, but also a restriction on one of the zcustomer attribs, with an index for that maybe, and performance should improve.
br
Jacob -
Bad Performance in a query into table BKPF
Hi forum i have a really problem in the second query under the table
BKPF.. some body cans help me, please
*THIS IS THE QUERY UNDER MSEG
SELECT tmsegmblnr tmkpfbudat tmsegbelnr tmsegbukrs tmseg~matnr
tmsegebelp tmsegdmbtr tmsegwaers tmsegwerks tmseg~lgort
tmsegmenge tmsegkostl
FROM mseg AS tmseg JOIN mkpf AS tmkpf ON tmsegmblnr = tmkpfmblnr
INTO CORRESPONDING FIELDS OF TABLE it_docs
WHERE
tmseg~bukrs IN se_bukrs AND
tmkpf~budat IN se_budat AND
tmseg~mjahr = d_gjahr AND
( tmsegbwart IN se_bwart AND tmsegbwart IN (201,261) ).
IF sy-dbcnt > 0.
I CREATE AWKEY FOR CONSULTING BKPF
LOOP AT it_docs.
CONCATENATE it_docs-mblnr d_gjahr INTO it_docs-d_awkey.
MODIFY it_docs.
ENDLOOP.
THIS IS THE QUERY WITH BAD BAD PERFOMANCE
I NEED KNOW "BELNR" FOR GO TO THE BSEG TABLE
SELECT belnr awkey
FROM bkpf
INTO CORRESPONDING FIELDS OF TABLE it_tmp
FOR ALL ENTRIES IN it_docs
WHERE
bukrs = it_docs-bukrs AND
awkey = it_docs-d_awkey AND
gjahr = d_gjahr AND
bstat = space .
THNKSHi Josue,
The bad performance is because you're not specifying the primary keys of the table BKPF in your WHERE condition; BKPF usually is a big table.
What you really need is to create a new index on database for table BKPF via the ABAP Dictionary on fields BUKRS, AWKEY, GJAHR & BSTAT. You'll find the performace of the program will significantly increase after the new index is activated. But I would talk to the Basis first to confirm they have no issues if you create a new index for BKPF on the database system.
Hope this helps.
Cheers,
Sougata. -
SQL Server 2014 - ColumnStore index Clustered with Merge Join
Hi All,
I would like to know in SQL Server 2014, the new feature "Clustered Columnstore". I had inserted 9 millions of records in to a clustered columnstore table.
Then i do a merge join query to insert and update to another table. The Merge join query is as below :
MERGE [dbo].[Temp_FactSales] AS TARGET
USING [dbo].[FactSales_9m] AS SOURCE
ON
TARGET.SALESID = SOURCE.SALESID
WHEN NOT MATCHED BY TARGET
THEN INSERT
[listid],
[sellerid],
[buyerid],
[eventid],
[dateid],
[qtysold],
[pricepaid],
[commission],
[saletime]
VALUES
SOURCE.[listid],
SOURCE.[sellerid],
SOURCE.[buyerid],
SOURCE.[eventid],
SOURCE.[dateid],
SOURCE.[qtysold],
SOURCE.[pricepaid],
SOURCE.[commission],
SOURCE.[saletime]
WHEN MATCHED THEN
UPDATE
SET
TARGET.[listid] = SOURCE.[listid],
TARGET.[sellerid] = SOURCE.[sellerid],
TARGET.[buyerid] = SOURCE.[buyerid],
TARGET.[eventid] = SOURCE.[eventid],
TARGET.[dateid] = SOURCE.[dateid],
TARGET.[qtysold] = SOURCE.[qtysold],
TARGET.[pricepaid] = SOURCE.[pricepaid],
TARGET.[commission] = SOURCE.[commission],
TARGET.[saletime] = SOURCE.[saletime]
The total execute time is about 10 mins. However if i removed the Columnstore index in the table which using normal primary key. Then the execution time is less than 1 mins.
My question is when using "merge join", is this the behavior for columnstore index ? As from what i read, Columnstore index is great performance in read the data but not doing "Insert, update and Delete"?
Hope anyone can help.
Thanks a lot.Hi TTL1964,
How's everything going?
If there is any progress from your side, feel free to share it in the forum.
Thanks.
Tracy Cai
TechNet Community Support -
Why is LOWER function producing a cartesian merge join, when UPPER doesn't?
Hi there,
I have an odd scenario that I would like to understand correctly...
We have a query that is taking a long time to run on one of our databases, further investigation of the explain plan showed that the query was in fact producing a Cartesian merge join even though there is clearly join criteria specified. I know that the optimiser can and will do this if it is a more efficient way of producing the results, however in this scenario it is producing the Cartesian merge on two unrelated tables and seemingly ignoring the Join condition...
*** ORIGINAL QUERY ***
SELECT count(*)
FROM srs_sce sce,
srs_scj scj,
men_mre mre,
srs_mst mst,
cam_smo cam,
ins_spr spr,
men_mua mua,
temp_webct_users u
WHERE sce.sce_scjc = scj.scj_code
AND sce.sce_stuc = mre.mre_code
AND mst.mst_code = mre.mre_mstc
AND mre.mre_mrcc = 'STU'
AND mst.mst_code = mua.mua_mstc
AND cam.ayr_code = sce.sce_ayrc
AND cam.spr_code = scj.scj_sprc
AND spr.spr_code = scj.scj_sprc
-- Ignored Join Condition
AND LOWER(mua.mua_extu) = LOWER(u.login)
AND SUBSTR (sce.sce_ayrc, 1, 4) = '2008'
AND sce.sce_stac IN ('RCE', 'RLL', 'RPD', 'RIN', 'RSAS', 'RHL_R', 'RCO', 'RCI', 'RCA');
*** CARTESIAN EXPLAIN PLAN ***
SELECT STATEMENT CHOOSECost: 83
20 NESTED LOOPS Cost: 83 Bytes: 176 Cardinality: 1
18 NESTED LOOPS Cost: 82 Bytes: 148 Cardinality: 1
15 NESTED LOOPS Cost: 80 Bytes: 134 Cardinality: 1
13 NESTED LOOPS Cost: 79 Bytes: 123 Cardinality: 1
10 NESTED LOOPS Cost: 78 Bytes: 98 Cardinality: 1
7 NESTED LOOPS Cost: 77 Bytes: 74 Cardinality: 1
NOTE: The Cartesian product is performed on the men_mre & temp_webct_users tables not the men_mua mua & temp_webct_users tables specified in the join condition.
4 MERGE JOIN CARTESIAN Cost: 74 Bytes: 32 Cardinality: 1
1 TABLE ACCESS FULL EXETER.TEMP_WEBCT_USERS Cost: 3 Bytes: 6 Cardinality: 1
3 BUFFER SORT Cost: 71 Bytes: 1,340,508 Cardinality: 51,558
2 TABLE ACCESS FULL SIPR.MEN_MRE Cost: 71 Bytes: 1,340,508 Cardinality: 51,558
6 TABLE ACCESS BY INDEX ROWID SIPR.SRS_SCE Cost: 3 Bytes: 42 Cardinality: 1
5 INDEX RANGE SCAN SIPR.SRS_SCEI3 Cost: 2 Cardinality: 3
9 TABLE ACCESS BY INDEX ROWID SIPR.SRS_SCJ Cost: 1 Bytes: 24 Cardinality: 1
8 INDEX UNIQUE SCAN SIPR.SRS_SCJP1 Cardinality: 1
12 TABLE ACCESS BY INDEX ROWID SIPR.INS_SPR Cost: 1 Bytes: 25 Cardinality: 1
11 INDEX UNIQUE SCAN SIPR.INS_SPRP1 Cardinality: 1
14 INDEX UNIQUE SCAN SIPR.SRS_MSTP1 Cost: 1 Bytes: 11 Cardinality: 1
17 TABLE ACCESS BY INDEX ROWID SIPR.MEN_MUA Cost: 2 Bytes: 14 Cardinality: 1
16 INDEX RANGE SCAN SIPR.MEN_MUAI3 Cost: 2 Cardinality: 1
19 INDEX RANGE SCAN SIPR.CAM_SMOP1 Cost: 2 Bytes: 28 Cardinality: 1 After speaking with data experts I realised one of the fields being LOWERed for the join condition generally always had uppercase values so I tried modifying the query to use the UPPER function rather than the LOWER one originally used, in this scenario the query executed in seconds and the Cartesian merge had been eradicated which by all accounts is a good result.
*** WORKING QUERY ***
SELECT count(*)
FROM srs_sce sce,
srs_scj scj,
men_mre mre,
srs_mst mst,
cam_smo cam,
ins_spr spr,
men_mua mua,
temp_webct_users u
WHERE sce.sce_scjc = scj.scj_code
AND sce.sce_stuc = mre.mre_code
AND mst.mst_code = mre.mre_mstc
AND mre.mre_mrcc = 'STU'
AND mst.mst_code = mua.mua_mstc
AND cam.ayr_code = sce.sce_ayrc
AND cam.spr_code = scj.scj_sprc
AND spr.spr_code = scj.scj_sprc
-- Working Join Condition
AND UPPER(mua.mua_extu) = UPPER(u.login)
AND SUBSTR (sce.sce_ayrc, 1, 4) = '2008'
AND sce.sce_stac IN ('RCE', 'RLL', 'RPD', 'RIN', 'RSAS', 'RHL_R', 'RCO', 'RCI', 'RCA');
*** WORKING EXPLAIN PLAN ***
SELECT STATEMENT CHOOSECost: 13
20 SORT AGGREGATE Bytes: 146 Cardinality: 1
19 NESTED LOOPS Cost: 13 Bytes: 146 Cardinality: 1
17 NESTED LOOPS Cost: 12 Bytes: 134 Cardinality: 1
15 NESTED LOOPS Cost: 11 Bytes: 115 Cardinality: 1
12 NESTED LOOPS Cost: 10 Bytes: 91 Cardinality: 1
9 NESTED LOOPS Cost: 7 Bytes: 57 Cardinality: 1
6 NESTED LOOPS Cost: 6 Bytes: 31 Cardinality: 1
4 NESTED LOOPS Cost: 5 Bytes: 20 Cardinality: 1
1 TABLE ACCESS FULL EXETER.TEMP_WEBCT_USERS Cost: 3 Bytes: 6 Cardinality: 1
3 TABLE ACCESS BY INDEX ROWID SIPR.MEN_MUA Cost: 2 Bytes: 42 Cardinality: 3
2 INDEX RANGE SCAN EXETER.TEST Cost: 1 Cardinality: 1
5 INDEX UNIQUE SCAN SIPR.SRS_MSTP1 Cost: 1 Bytes: 11 Cardinality: 1
8 TABLE ACCESS BY INDEX ROWID SIPR.MEN_MRE Cost: 2 Bytes: 26 Cardinality: 1
7 INDEX RANGE SCAN SIPR.MEN_MREI2 Cost: 2 Cardinality: 1
11 TABLE ACCESS BY INDEX ROWID SIPR.SRS_SCE Cost: 3 Bytes: 34 Cardinality: 1
10 INDEX RANGE SCAN SIPR.SRS_SCEI3 Cost: 2 Cardinality: 3
14 TABLE ACCESS BY INDEX ROWID SIPR.SRS_SCJ Cost: 1 Bytes: 24 Cardinality: 1
13 INDEX UNIQUE SCAN SIPR.SRS_SCJP1 Cardinality: 1
16 INDEX RANGE SCAN SIPR.CAM_SMOP1 Cost: 2 Bytes: 19 Cardinality: 1
18 INDEX UNIQUE SCAN SIPR.INS_SPRP1 Bytes: 12 Cardinality: 1 *** RESULT ***
COUNT(*)
83299I am still struggling to understand why this would have worked as to my knowledge the LOWER & UPPER functions are similar enough in function and regardless of that why would one version cause the optimiser to effectively ignore a join condition.
If anyone can shed any light on this for me it would be very much appreciated.
Regards,
Kieron
Edited by: Kieron_Bird on Nov 19, 2008 6:09 AM
Edited by: Kieron_Bird on Nov 19, 2008 6:41 AMMy mistake on the predicate information, was in a rush to run off to a meeting when I posted the entry...
*** UPPER Version of the Explain Plan ***
| Id | Operation | Name | Rows | Bytes | Cost | TQ |IN-OUT| PQ Distrib |
| 0 | SELECT STATEMENT | | 1 | 146 | 736 | | | |
| 1 | SORT AGGREGATE | | 1 | 146 | | | | |
| 2 | SORT AGGREGATE | | 1 | 146 | | 86,10 | P->S | QC (RAND) |
|* 3 | HASH JOIN | | 241 | 35186 | 736 | 86,10 | PCWP | |
|* 4 | HASH JOIN | | 774 | 105K| 733 | 86,09 | P->P | HASH |
|* 5 | HASH JOIN | | 12608 | 1489K| 642 | 86,08 | P->P | BROADCAST |
| 6 | NESTED LOOPS | | 14657 | 1531K| 491 | 86,07 | P->P | HASH |
|* 7 | HASH JOIN | | 14657 | 1359K| 490 | 86,07 | PCWP | |
|* 8 | HASH JOIN | | 14371 | 996K| 418 | 86,06 | P->P | HASH |
|* 9 | TABLE ACCESS FULL | SRS_SCE | 3211 | 106K| 317 | 86,00 | S->P | BROADCAST |
|* 10 | HASH JOIN | | 52025 | 1879K| 101 | 86,06 | PCWP | |
|* 11 | TABLE ACCESS FULL | MEN_MRE | 51622 | 1310K| 71 | 86,01 | S->P | HASH |
| 12 | INDEX FAST FULL SCAN| SRS_MSTP1 | 383K| 4119K| 30 | 86,05 | P->P | HASH |
| 13 | TABLE ACCESS FULL | SRS_SCJ | 114K| 2672K| 72 | 86,02 | S->P | HASH |
|* 14 | INDEX UNIQUE SCAN | INS_SPRP1 | 1 | 12 | | 86,07 | PCWP | |
| 15 | TABLE ACCESS FULL | MEN_MUA | 312K| 4268K| 151 | 86,03 | S->P | HASH |
| 16 | INDEX FAST FULL SCAN | CAM_SMOP1 | 527K| 9796K| 91 | 86,09 | PCWP | |
| 17 | TABLE ACCESS FULL | TEMP_WEBCT_USERS | 33276 | 194K| 3 | 86,04 | S->P | HASH |
Predicate Information (identified by operation id):
3 - access(UPPER("MUA"."MUA_EXTU")=UPPER("U"."LOGIN"))
4 - access("CAM"."AYR_CODE"="SCE"."SCE_AYRC" AND "CAM"."SPR_CODE"="SCJ"."SCJ_SPRC")
5 - access("MST"."MST_CODE"="MUA"."MUA_MSTC")
7 - access("SCE"."SCE_SCJC"="SCJ"."SCJ_CODE")
8 - access("SCE"."SCE_STUC"="MRE"."MRE_CODE")
9 - filter(SUBSTR("SCE"."SCE_AYRC",1,4)='2008' AND ("SCE"."SCE_STAC"='RCA' OR "SCE"."SCE_STAC"='RCE' OR
"SCE"."SCE_STAC"='RCI' OR "SCE"."SCE_STAC"='RCO' OR "SCE"."SCE_STAC"='RHL_R' OR "SCE"."SCE_STAC"='RIN' OR
"SCE"."SCE_STAC"='RLL' OR "SCE"."SCE_STAC"='RPD' OR "SCE"."SCE_STAC"='RSAS'))
10 - access("MST"."MST_CODE"="MRE"."MRE_MSTC")
11 - filter("MRE"."MRE_MRCC"='STU')
14 - access("SPR"."SPR_CODE"="SCJ"."SCJ_SPRC")
Note: cpu costing is off
40 rows selected.*** LOWER Version of the Explain Plan ***
| Id | Operation | Name | Rows | Bytes | Cost | TQ |IN-OUT| PQ Distrib |
| 0 | SELECT STATEMENT | | 1 | 146 | 736 | | | |
| 1 | SORT AGGREGATE | | 1 | 146 | | | | |
| 2 | SORT AGGREGATE | | 1 | 146 | | 88,10 | P->S | QC (RAND) |
|* 3 | HASH JOIN | | 257K| 35M| 736 | 88,10 | PCWP | |
|* 4 | HASH JOIN | | 774 | 105K| 733 | 88,09 | P->P | HASH |
|* 5 | HASH JOIN | | 12608 | 1489K| 642 | 88,08 | P->P | BROADCAST |
| 6 | NESTED LOOPS | | 14657 | 1531K| 491 | 88,07 | P->P | HASH |
|* 7 | HASH JOIN | | 14657 | 1359K| 490 | 88,07 | PCWP | |
|* 8 | HASH JOIN | | 14371 | 996K| 418 | 88,06 | P->P | HASH |
|* 9 | TABLE ACCESS FULL | SRS_SCE | 3211 | 106K| 317 | 88,00 | S->P | BROADCAST |
|* 10 | HASH JOIN | | 52025 | 1879K| 101 | 88,06 | PCWP | |
|* 11 | TABLE ACCESS FULL | MEN_MRE | 51622 | 1310K| 71 | 88,01 | S->P | HASH |
| 12 | INDEX FAST FULL SCAN| SRS_MSTP1 | 383K| 4119K| 30 | 88,05 | P->P | HASH |
| 13 | TABLE ACCESS FULL | SRS_SCJ | 114K| 2672K| 72 | 88,02 | S->P | HASH |
|* 14 | INDEX UNIQUE SCAN | INS_SPRP1 | 1 | 12 | | 88,07 | PCWP | |
| 15 | TABLE ACCESS FULL | MEN_MUA | 312K| 4268K| 151 | 88,03 | S->P | HASH |
| 16 | INDEX FAST FULL SCAN | CAM_SMOP1 | 527K| 9796K| 91 | 88,09 | PCWP | |
| 17 | TABLE ACCESS FULL | TEMP_WEBCT_USERS | 33276 | 194K| 3 | 88,04 | S->P | HASH |
Predicate Information (identified by operation id):
3 - access(LOWER("MUA"."MUA_EXTU")=LOWER("U"."LOGIN"))
4 - access("CAM"."AYR_CODE"="SCE"."SCE_AYRC" AND "CAM"."SPR_CODE"="SCJ"."SCJ_SPRC")
5 - access("MST"."MST_CODE"="MUA"."MUA_MSTC")
7 - access("SCE"."SCE_SCJC"="SCJ"."SCJ_CODE")
8 - access("SCE"."SCE_STUC"="MRE"."MRE_CODE")
9 - filter(SUBSTR("SCE"."SCE_AYRC",1,4)='2008' AND ("SCE"."SCE_STAC"='RCA' OR "SCE"."SCE_STAC"='RCE' OR
"SCE"."SCE_STAC"='RCI' OR "SCE"."SCE_STAC"='RCO' OR "SCE"."SCE_STAC"='RHL_R' OR "SCE"."SCE_STAC"='RIN' OR
"SCE"."SCE_STAC"='RLL' OR "SCE"."SCE_STAC"='RPD' OR "SCE"."SCE_STAC"='RSAS'))
10 - access("MST"."MST_CODE"="MRE"."MRE_MSTC")
11 - filter("MRE"."MRE_MRCC"='STU')
14 - access("SPR"."SPR_CODE"="SCJ"."SCJ_SPRC")
Note: cpu costing is off
40 rows selected.As you state something has obviously changed, but nothing obvious has been changed.
We gather statistics via...
exec dbms_stats.gather_schema_stats(ownname => 'USERNAME', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE , degree => 4, granularity => ''ALL'', cascade => TRUE);
We run a script nightly which works out which indexes require a rebuild and rebuild those only it doesn;t just rebuild all indexes.
It would be nice to be able to use the 10g statistics history, but on this instance we aren't yet at that version, hopefully we will be there soon though.
Hope this helps,
Kieron -
Facing Merge Join Cartersian in the explain plan after adding gl periods
Hi All
I have added gl periods table to the below query , checked the explain plan and it shows merge join cartesian. This query is taking long time to fetch the results.
Need help ASAP , Please let me know where i am going wrong . Any suggestions will be appreciated.
SELECT gljh.period_name, gljh.ledger_id, gljh.je_source,
glcc.segment2,
SUM ( NVL (gljl.accounted_dr, 0)
- NVL (gljl.accounted_cr, 0)
) total_amt,
gljh.currency_code
FROM gl_je_headers gljh,
gl_je_lines gljl,
gl_code_combinations glcc,
gl_periods gps
WHERE 1=1
AND gljh.period_name = gps.period_name
AND gljl.period_name = gps.period_name
AND gps.period_set_name = 'MCD_MONTH_'
AND gps.start_date >= :p_from_date
AND gps.start_date <= :p_to_date
AND gljh.ledger_id = :p_ledger_id
AND gljh.je_header_id = gljl.je_header_id
AND gljl.code_combination_id = glcc.code_combination_id
AND glcc.segment2 = '10007'--get_segment2_rec.flex_value
AND gljh.currency_code <> 'STAT'
GROUP BY gljh.je_source,
gljh.period_name,
glcc.segment2,
gljh.ledger_id,
gljh.currency_code
HAVING SUM ( NVL (gljl.accounted_dr, 0)
- NVL (gljl.accounted_cr, 0)
) <> 0;
Plan
SELECT STATEMENT ALL_ROWSCost: 73,146 Bytes: 2,266 Cardinality: 22
15 FILTER
14 HASH GROUP BY Cost: 73,146 Bytes: 2,266 Cardinality: 22
13 FILTER
12 NESTED LOOPS Cost: 73,145 Bytes: 61,079 Cardinality: 593
9 NESTED LOOPS Cost: 31,603 Bytes: 1,452,780 Cardinality: 20,754
6 MERGE JOIN CARTESIAN Cost: 2,108 Bytes: 394,181 Cardinality: 9,167
2 TABLE ACCESS BY INDEX ROWID TABLE GL.GL_PERIODS Cost: 4 Bytes: 31 Cardinality: 1
1 INDEX RANGE SCAN INDEX (UNIQUE) GL.GL_PERIODS_U2 Cost: 1 Cardinality: 64
5 BUFFER SORT Cost: 2,104 Bytes: 683,988 Cardinality: 56,999
4 TABLE ACCESS BY INDEX ROWID TABLE GL.GL_CODE_COMBINATIONS Cost: 2,104 Bytes: 683,988 Cardinality: 56,999
3 INDEX RANGE SCAN INDEX GL.GL_CODE_COMBINATIONS_N2 Cost: 155 Cardinality: 56,999
8 TABLE ACCESS BY INDEX ROWID TABLE GL.GL_JE_LINES Cost: 18 Bytes: 54 Cardinality: 2
7 INDEX RANGE SCAN INDEX GL.GL_JE_LINES_N1 Cost: 3 Cardinality: 37
11 TABLE ACCESS BY INDEX ROWID TABLE GL.GL_JE_HEADERS Cost: 2 Bytes: 33 Cardinality: 1
10 INDEX UNIQUE SCAN INDEX (UNIQUE) GL.GL_JE_HEADERS_U1 Cost: 1 Cardinality: 1
Thanks
ChandraLots of things come into play when you're tuning a query.
An (unformatted) execution plan isn't enough.
Tuning takes time and understanding how (a lot of) things work, there is no ASAP in the world of tuning.
Please post other important details, like your database version, optimizer settings, how/when are table statistics gathered etc.
So, read the following informative threads (and please take your time, this really is important stuff), and adust your thread as needed.
That way you'll have a bigger chance of getting help that makes sense...
Your DBA should/ought to be able to help you in this as well.
Re: HOW TO: Post a SQL statement tuning request - template posting
http://oracle-randolf.blogspot.com/2009/02/basic-sql-statement-performance.html -
Group by causing merge join cartesian?
Hi All,
Database Version: Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
Database Version: PL/SQL Release 10.2.0.5.0 - ProductionI've written a query which runs in under a second and produces a few hundred rows (as you can see below). I only wanted to find the number of distinct incident ID's returned so I put a group by at the end and it ran for ever.
I produced an explain plan (as shown below) for the query with the group by in it and it is trying to perform a cartesian join!
WTF is going on? I've never known a group by statement to do that before.
basic structure of the tables is as follows:
SQL> desc answer_master
Name Null? Type
ANSWER_ID NOT NULL NUMBER(12)
INCIDENT_ID NOT NULL NUMBER(12)
PLAN_ID NOT NULL NUMBER(12)
QUESTION_ID NOT NULL NUMBER(12)
SQL> desc question_master
Name Null? Type
QUESTION_PLAN_ID NOT NULL NUMBER(12)
QUESTION_ID NOT NULL NUMBER(12)
QUESTION_TYPE NOT NULL NUMBER(2)
QUESTION_TEXT NOT NULL VARCHAR2(255)
QUESTION_PARENT_ID NUMBER(12)the offending SQL statement
SQL> explain plan for
2 select incident_id
3 from answer_master am
4 where exists (select 'x'
5 from answer_master am1
6 where question_id in (select question_id
7 from question_master qms
8 where question_plan_id = 1477
9 and question_parent_id = 69067
10 and substr(question_text,-3) = 'PDF')
11 and am1.incident_id = am.incident_id)
12 and exists (select 'x'
13 from answer_master am1
14 where question_id in (select question_id
15 from question_master qms
16 where question_plan_id = 1477
17 and question_parent_id = 69067
18 and substr(question_text,-3) != 'PDF')
19 and am1.incident_id = am.incident_id);
Explained.
Elapsed: 00:00:00.01
SQL> set linesize 132;
SQL> select plan_table_output from table(dbms_xplan.display('plan_table',null,'serial'));
PLAN_TABLE_OUTPUT
Plan hash value: 1710257923
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 32 | 171 (6)| 00:00:01 |
|* 1 | HASH JOIN RIGHT SEMI | | 1 | 32 | 171 (6)| 00:00:01 |
| 2 | VIEW | VW_SQ_2 | 71 | 923 | 70 (5)| 00:00:01 |
| 3 | NESTED LOOPS | | 71 | 3266 | 70 (5)| 00:00:01 |
|* 4 | TABLE ACCESS BY INDEX ROWID | QUESTION_MASTER | 1 | 35 | 2 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | QUESTION_MASTER_IX1 | 3 | | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | ANSWER_MASTER_QID_IX2 | 18731 | 201K| 68 (5)| 00:00:01 |
| 7 | NESTED LOOPS | | 304 | 5776 | 100 (5)| 00:00:01 |
| 8 | VIEW | VW_SQ_1 | 14 | 182 | 70 (5)| 00:00:01 |
| 9 | HASH UNIQUE | | 14 | 644 | | |
| 10 | NESTED LOOPS | | 14 | 644 | 70 (5)| 00:00:01 |
|* 11 | TABLE ACCESS BY INDEX ROWID| QUESTION_MASTER | 1 | 35 | 2 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | QUESTION_MASTER_IX1 | 3 | | 1 (0)| 00:00:01 |
|* 13 | INDEX RANGE SCAN | ANSWER_MASTER_QID_IX2 | 18731 | 201K| 68 (5)| 00:00:01 |
|* 14 | INDEX RANGE SCAN | ANSWER_MASTER_QID_IX3 | 22 | 132 | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("ITEM_2"="AM"."INCIDENT_ID")
4 - filter("QUESTION_PLAN_ID"=1477 AND SUBSTR("QUESTION_TEXT",-3)!='PDF')
5 - access("QUESTION_PARENT_ID"=69067)
6 - access("QUESTION_ID"="QUESTION_ID")
11 - filter("QUESTION_PLAN_ID"=1477 AND SUBSTR("QUESTION_TEXT",-3)='PDF')
12 - access("QUESTION_PARENT_ID"=69067)
13 - access("QUESTION_ID"="QUESTION_ID")
14 - access("ITEM_1"="AM"."INCIDENT_ID")
33 rows selected.
Elapsed: 00:00:00.06
SQL> explain plan for
2 select incident_id
3 from answer_master am
4 where exists (select 'x'
5 from answer_master am1
6 where question_id in (select question_id
7 from question_master qms
8 where question_plan_id = 1477
9 and question_parent_id = 69067
10 and substr(question_text,-3) = 'PDF')
11 and am1.incident_id = am.incident_id)
12 and exists (select 'x'
13 from answer_master am1
14 where question_id in (select question_id
15 from question_master qms
16 where question_plan_id = 1477
17 and question_parent_id = 69067
18 and substr(question_text,-3) != 'PDF')
19 and am1.incident_id = am.incident_id)
20 group by incident_id;
Explained.
Elapsed: 00:00:00.00
SQL> select plan_table_output from table(dbms_xplan.display('plan_table',null,'serial'));
PLAN_TABLE_OUTPUT
Plan hash value: 1433543102
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 98 | 77 (6)| 00:00:01 |
| 1 | HASH GROUP BY | | 1 | 98 | 77 (6)| 00:00:01 |
| 2 | NESTED LOOPS | | 1 | 98 | 76 (4)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 87 | 74 (5)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 81 | 72 (5)| 00:00:01 |
| 5 | MERGE JOIN CARTESIAN | | 1 | 70 | 4 (0)| 00:00:01 |
|* 6 | TABLE ACCESS BY INDEX ROWID | QUESTION_MASTER | 1 | 35 | 2 (0)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | QUESTION_MASTER_IX1 | 3 | | 1 (0)| 00:00:01 |
| 8 | BUFFER SORT | | 1 | 35 | 2 (0)| 00:00:01 |
|* 9 | TABLE ACCESS BY INDEX ROWID| QUESTION_MASTER | 1 | 35 | 2 (0)| 00:00:01 |
|* 10 | INDEX RANGE SCAN | QUESTION_MASTER_IX1 | 3 | | 1 (0)| 00:00:01 |
|* 11 | INDEX RANGE SCAN | ANSWER_MASTER_QID_IX2 | 18731 | 201K| 68 (5)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | ANSWER_MASTER_QID_IX3 | 22 | 132 | 2 (0)| 00:00:01 |
|* 13 | INDEX RANGE SCAN | ANSWER_MASTER_QID_IX2 | 1 | 11 | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
6 - filter("QUESTION_PLAN_ID"=1477 AND SUBSTR("QUESTION_TEXT",-3)='PDF')
7 - access("QUESTION_PARENT_ID"=69067)
9 - filter("QUESTION_PLAN_ID"=1477 AND SUBSTR("QUESTION_TEXT",-3)!='PDF')
10 - access("QUESTION_PARENT_ID"=69067)
11 - access("QUESTION_ID"="QUESTION_ID")
12 - access("AM1"."INCIDENT_ID"="AM"."INCIDENT_ID")
13 - access("QUESTION_ID"="QUESTION_ID" AND "AM1"."INCIDENT_ID"="AM"."INCIDENT_ID")
31 rows selected.
Elapsed: 00:00:00.00
SQL> spool offedit: changing greater-than/less-than signs to != so it displays on forum
Edited by: WhiteHat on Feb 11, 2011 9:37 AMThe "Cartesian" product is nothing "wrong", if (!) the optimizer is right and the number or rows it's picking for that part of the execution plan is really 1. And that can be true, as ORACLE also changed from HASH join to NL. So that NL might be the cause of your performance issue not the Cartesian.
The performance of IN, EXISTS and SUBQUERIES got better over the versions, but I still see no reason in most cases to use them for good readable and performing code.
What you do think about this:
WITH my_selection As
(SELECT incident_id
from question_master qms
where question_plan_id = 1477
and question_parent_id = 69067
and (substr(question_text,-3) = 'PDF'
or and substr(question_text,-3) != 'PDF')
GROUP BY incident_id
HAVING COUNT(*) >1)
SELECT am.incident_id
FROM answer_master am
INNER JOIN my_selection s
ON am.incident_id = s.incident_id
group by am.incident_id; -
I have query whch when I do showplan ...
It show merge join is happening at client place and
not at mine....
Can anybody suggest as what is reason behind this
merge join to occur.
Merge join should not occur at any cost...
It is slowing down my performance of Query and taking lot of time...Impossible to tell without viewing the query. Please post the 'offending' statement.
-
Problem with SQL to create a temp table to evaluate sort merge join
Can anyone help me with the below sql to enable the performance of the use merge join to be evaluated. This sql is placed in a file and ran from the prompt.
timing start
CREATE table testsql as
SELECT /*+ USE_MERGE(t1000 t8000)*/ t1000, t8000
FROM t1000, t8000
WHERE t1000.ONEPERCENT=1 AND t1000.unique1 = t8000.fk;
timing stop
drop table testsql;
Current error message:
SQL> start h:\exe1.sql
SELECT /*+ USE_MERGE(t1000 t8000)*/ t1000, t8000
ERROR at line 2:
ORA-00904: "T8000": invalid identifier
Elapsed: 00:00:00.01
drop table testsql
ERROR at line 1:
ORA-00942: table or view does not exist
Thanks for your help,
Regards, Chris.SELECT /*+ USE_MERGE(t1000 t8000)*/ t1000, t8000
Are you sure you have columns t1000 and t8000 in one of your tables used in the from clause?
What is the idea of this exercise? what is it that you are trying to evaluate? -
Nested loop, merge join and harsh join
Can any one tell me the difference/relationship between nested loop, harsh join and merge join...Thanx
Check Oracle Performance Tuning Guide
13.6 Understanding Joins
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#i51523 -
Merge Join Cartesian in XML query
Hi Sir
I am getting Merge join cartesian in the below XML query
SELECT
x.empno,
x1.empno AS INDEXempno
FROM
emp_vw x,
emp_index x1,
table (xmlsequence(extract(x1.xml_data,'/emp/org/constituent/'))) c
WHERE x.empno = extractvalue(VALUE(c),'/constituent/code/text()');
I am getting Merge join cartesian in XML query. whereeas below query i am running by I am not getting merge join cartesian
SELECT
x.empno,
x1.empno AS INDEXempno
FROM
emp_vw_v6 x,
emp_index_v6 x1,
table (xmlsequence(extract(x1.xml_data,'/emp/org/constituent/'))) c
WHERE x.empno = extractvalue(VALUE(c),'/constituent/code/text()');
Here emp_vw is a view and emp_index is a table.This is not giving merge join cartesian
However both the view and table are interdependent.
Please help me to resolve the performance of the first query as it is taking a lot of time to execute.?
Thanks & Regards
Thakur Manoj RPlease post a working test case, and follow the guidelines here : {message:id=9360002}
What are the differences between the view and table in the first query and the two others (*_v6) in the second query? -
CMP 6.1 Entity bad performance.
I'am using entity 1.1 EJB on WL 6.1 and facing very bad performances:
around 150ms for an insert (i have 20 columns).
When accessing an order interface to read 2 fields in a session bean method: around
90 ms.
I'am very disapointed and confused. What should I look up for
to increase the performance ? Any important tuning or parameters ? Should I use EJB
2.0 to have significant perf ?
Thanks for any advice because we are thinking to switch all the application on stored
procedures. A solution without Entity and fewer stateless session beans.
My config:
WL: 6.1 on Sun sparc
SGBD: Sybase
Entity: WebLogic 6.0.0 EJB 1.1 RDBMS (weblogic-rdbms11-persistence-600.dtd)
ThanksHistorically its hard to get good performance & scalability out of sybase
without using stored procs. Using dynamic sql on sybase just doesnt do as
well as procs. Oracle on the other hand can get very close to stored proc
speed out of well written dynamic sql.
As far as weblogic goes, my experience is the focus of their testing for db
related stuff is Oracle, then DB2, then MSSQLServer. Sybase is usually last
on the list.
As far as the 6.1 cmp, haven't used it much, but because of these other
things I would be cautious about using it with Sybase.
Joel
"Antoine Bas" <[email protected],> wrote in message
news:3cc7cdcf$[email protected]..
>
I'am using entity 1.1 EJB on WL 6.1 and facing very bad performances:
around 150ms for an insert (i have 20 columns).
When accessing an order interface to read 2 fields in a session beanmethod: around
90 ms.
I'am very disapointed and confused. What should I look up for
to increase the performance ? Any important tuning or parameters ? ShouldI use EJB
2.0 to have significant perf ?
Thanks for any advice because we are thinking to switch all theapplication on stored
procedures. A solution without Entity and fewer stateless session beans.
My config:
WL: 6.1 on Sun sparc
SGBD: Sybase
Entity: WebLogic 6.0.0 EJB 1.1 RDBMS(weblogic-rdbms11-persistence-600.dtd)
>
Thanks
Maybe you are looking for
-
My iPhoto library is gone, and I don't know where. My system was slow, so I ran the Disc Utility and it told me the disc needed repair. I took it to an Apple Store genius bar. The "genius" told me the disc was dying, slowly. He got me to buy a portab
-
Receiving Error in Shopping Cart : Order Does not exist
Hi While creating Shopping Cart and click Insert From Clipboard button, I am receiving " Order xxxx does not exist (Item yyy ). Please tell me why I receive this error and what causes and possible fixes to this? Details: The scenario I am doing is I
-
how well does the imac duo intel, with 1gb memory, play world of warcraft
-
I want to set up a shared storage area where family members can store content they want to share but be the only ones to have modify rights over their content. It would appear the Shares control with the NAS interface overrules whatever permissions a
-
Web start terminated unexpectedly
after installation is complete , reboot the system then i insert the intel installation cd in cd-rom but when system is configure itself then it gave me that message " Web start launcher terminated unexpectedlyand press any key to rebboot ".So i can'