Explain plan for long running query in oracle sql developer - sql

I have below select query which is long running and i want to view the query execution plan to understand why this query is long running and which statement in sql query affecting the query performance. I am using oracle sql developer and i checked the explain plan for the below query but did not understood it clearly which statement is effecting my query so as to optimize my query.
Select *
from PROVISIONING_LOG#FONIC_RETAIL PL
JOIN PROVISIONING_TASK#FONIC_RETAIL PT ON PL.PROVISIONING_TASK_ID = PT.ID JOIN SERVICE#FONIC_RETAIL SER ON PT.SERVICE_ID = SER.ID
JOIN TEMP_WF_DEF_ALL TT ON SER.SUBSCRIPTION_ID = TT.SUBSCRIPTION_ID
where PT.CODE='MIGOPT_PACK' and PT.DESCRIPTION Like '%CVB Request' AND PT.PARAMETERS LIKE '%OPERATION=ADD%' AND PL.RESPONSE_TYPE IS NULL AND PL.REQUEST IS NOT NULL
and ((to_char(PT.START_DATE,'YYYYMMDDHH24Mi') = to_char(TT.COMPLETE_DATE,'YYYYMMDDHH24Mi'))
or (to_char(PT.START_DATE,'YYYYMMDDHH24Mi') = to_char(TT.COMPLETE_DATE + 1/1440,'YYYYMMDDHH24Mi'))) AND
PL.TIME_STAMP < SYSDATE - numtodsinterval ( 30,'MINUTE' )
and PL.TIME_STAMP > SYSDATE - numtodsinterval ( 4,'HOUR' )
AND TT.START_DATE < SYSDATE - numtodsinterval ( 30,'MINUTE' )
and TT.START_DATE > SYSDATE - numtodsinterval ( 4,'HOUR' )
AND TT.WF_NAME IN
('Subscribe LIDL Community Flat',
'LDLMonatsFlatrate Subscribe');
Query execution plan for the above query:

As you are using a mix of local tables and remote tables. If the tables on the remote database are larger than the ones on the local database then you might need to use the DRIVING_SITE hint so the smaller of the set of tables are moved to the database issuing the call.
DRIVING_SITE

Related

Improve Query Performance, Adding where clause grids query to a halt

Running the following SQL results in a query that runs in around 0.338s
adding a where clause and query times out. All I want to achieve is a list of test results for a particular test_code
Result_Set will have many Test_Results on the index Result_Set_Row_ID
Date_Received_Index will have many Result_Sets on the index Result_Set_Row_ID
I have tried altering the order of JOINS, adding clauses to the join statements.
SELECT
Date_Received_Index.Registration_Number,
Date_Received_Index.Specimen_Number,
Result,
Result_Comment,
Result_Comment_Exp ,
Result_Exp,
Short_Exp,
Test_Code,
Test_Exp,
Test_Row_ID,
Units,
Result_Set.Set_Code ,
Result_Set.Date_Time_Authorised,
Result_Set.Date_Booked_In ,
Date_Received_Index.Discipline,
Date_Received_Index.Namespace
FROM
Result_Set
INNER JOIN Test_Result ON Result_Set.Result_Set_Row_ID = Test_Result.Result_Set_Row_ID
INNER JOIN Date_Received_Index ON (Date_Received_Index.Request_Row_ID = Result_Set.Request_Row_ID)
WHERE
DATEDIFF('D', Date_Received_Index.Date_Received, current_timestamp) < 1 AND
Date_Received_Index.Namespace = 'CHM'
adding a WHERE clause e.g.
DATEDIFF('D', Date_Received_Index.Date_Received, current_timestamp) < 1 AND
Date_Received_Index.Namespace = 'CHM'
AND Test_Code = 'K'
results in the query timing out
I would like to be able to construct an SQL statement that is performant and just selects the test_code specified in the where clause.
This comes down to the Query Plan. Can you share the query plan?
My suspicion is that the column Test_Code is not indexed and the addition to the WHERE clause is causing the optimizer to select the wrong query plan.
I think the SQL optimizer is not able to optimize the portion
DATEDIFF('D', Date_Received_Index.Date_Received, current_timestamp) < 1
without knowing your schema my question would be of the three columns used in the where clause Date_Received_Index.Date_Received, Date_Received_Index.Namespace, and Test_Code are any of these columns index. You already indicated Test_Code is not.
Depending on what version of Cache you are using you might try
SELECT
Date_Received_Index.Registration_Number,
Date_Received_Index.Specimen_Number,
Result,
Result_Comment,
Result_Comment_Exp ,
Result_Exp,
Short_Exp,
Test_Code,
Test_Exp,
Test_Row_ID,
Units,
Result_Set.Set_Code ,
Result_Set.Date_Time_Authorised,
Result_Set.Date_Booked_In ,
Date_Received_Index.Discipline,
Date_Received_Index.Namespace
FROM %PARALLEL
Result_Set
INNER JOIN Test_Result ON Result_Set.Result_Set_Row_ID = Test_Result.Result_Set_Row_ID
INNER JOIN Date_Received_Index ON (Date_Received_Index.Request_Row_ID = Result_Set.Request_Row_ID)
WHERE
DATEDIFF('D', Date_Received_Index.Date_Received, current_timestamp) < 1
AND Date_Received_Index.Namespace = 'CHM'
AND Test_Code = 'K'
Use of %PARALLEL can cause the query to be run using multiple threads. If the server has a large number of CPUs it may run faster even if it's not optimized.

Simplify SQL query to Interbase DB

I have WPF application which task is to drag data from Interbase DB. Note, that this DB is located on the remote network device. Also, Firebird ado.net data provider is used.
One of my query looks like:
SELECT
T1.ind_st,
T2.ttt,
T2.tdtdtd,
sumr
FROM ((SELECT ind_st,
Sum(r) AS sumR
FROM (SELECT ind_st,
rrr AS r
FROM srok_tel
WHERE date_ch = '23.07.2018 0:00:00'
AND srok_ch = '18'
AND ind_st >= 33049
AND ind_st <= 34717
UNION
SELECT ind_st,
-rrr AS r
FROM srok_tel
WHERE date_ch = '23.07.2018 0:00:00'
AND srok_ch = '12'
AND ind_st >= 33049
AND ind_st <= 34717
UNION
SELECT ind_st,
rrr AS r
FROM srok_tel
WHERE date_ch = '24.07.2018 0:00:00'
AND srok_ch IN ( 6, 12 )
AND ind_st >= 33049
AND ind_st <= 34717)
GROUP BY ind_st) T1
JOIN (SELECT ind_st,
ttt,
tdtdtd
FROM srok_tel
WHERE date_ch = '24.07.2018 0:00:00'
AND srok_ch = '12'
AND ind_st >= 33049
AND ind_st <= 34717) T2
ON T1.ind_st = T2.ind_st)
Yes, heavy, hard to read at first look and probably written in a wrong way, but my task is to drag all data with one query and I am NOT sql pro.
Target table (SROK_TEL), from with data is selecting, contains aproximately 10^7 rows. Query run time is about 90 seconds, which is significantly more, then I wish to see.
Any suggestions about how to make this query work faster?
UPDATE1: On luisarcher's request I've added a query plan (hope that's exactly what he asked for)
PLAN JOIN (SORT ((T1 SROK_TEL NATURAL)
PLAN (T1 SROK_TEL NATURAL)
PLAN (T1 SROK_TEL NATURAL)), T2 SROK_TEL INDEX (PK_SROK_TEL))
I've had an issue like yours not long ago, so I'll share some tips that apply to your situation:
1) If you don't mind having duplicates, you can use UNION ALL instead of UNION. You can see why here
2) Restrict the data you use. This one is important; I got about 90% of execution time reduced by correctly removing data I don't need from the query (more specific where clauses, not selecting useless data).
3) Check if you can add an index in your table srok_tel.

Migrate query with START WITH and CONNECT BY PRIOR from oracle to postgresql

I am migrating a process from oracle to postgresql, and I am in another problem with the conversion of them.
I have been researching how to migrate an oracle query, which has "START WITH" and "CONNECT BY PRIOR", I have documented with respect to this, and I think the easiest way to do it is with "WITH RECURSIVE"
Make the migration of the query, but I'm not sure about the results they throw since the bd oracle and postgres are different, and it is not possible to homologate the bd.
This is the query in Oracle
SELECT edef_codigo, etdf_transac, edef_detail--, LEVEL
FROM edeft
WHERE edef_distrib in('OM', 'N/A')
AND pers_codigo_socadm = 311745439
AND ctac_correlativo = 7513
START WITH etdf_transac = 'SDN'
CONNECT BY PRIOR edef_codigo = edef_padre;
And this is the query in postgresql
WITH RECURSIVE edf AS ( SELECT ed.edef_codigo, ed.etdf_transac,
ed.edef_detail
FROM edeft ed
WHERE ed.edef_distrib in('OM', 'N/A')
AND ed.pers_codigo_socadm = 311745439
AND ed.ctac_correlativo = 7513
AND ed.etdf_transac = 'SDN'
UNION ALL
SELECT ed.edef_codigo, ed.etdf_transac,
ed.edef_detail
FROM edeft ed
JOIN edf ON edf.edef_codigo = ed.edef_padre
WHERE ed.edef_distrib in('OM', 'N/A')
AND ed.pers_codigo_socadm = 311745439
AND ed.ctac_correlativo = 7513
)
SELECT * FROM edf;
I am still new to postgres and this consultation has made me especially complicated, since I have not found examples similar to what I have.
Yes, I have also used "Connect by prior" conversion in Postgresql using "With Recursive" queries And I find this is the right approach.
One simple example in reference to connect by prior:
Oracle:
Select name, age from user_test connect by prior user_id=parent_id start with user_id='a';
Postgres:
with recursive cte_name as
(select u1.name, u1.user_id, u1.age from user_test u1 where user_id='a'
UNION ALL select u2.name, u2.user_id, u2.age from user_test u2
join cte_name on cte_name.user_id=u2.parent_id) select name,age from cte_name;

How to force the use of index in a specific relation on Oracle sql sentence

First, these queries are executed on Oracle 11g
I am trying to force the Oracle to execute the index on the condition manh_dist(tjoin1.fv,tjoin2.fv)<=8000 of the query bellow I am using hints to do it. However, it is not working.
This query:
SELECT /*+ INDEX(joinresult.tjoin1) */ count(*)
FROM
(SELECT tjoin1.fv, tjoin1.photoid
FROM minfv tjoin2, cophirfv500k tjoin1
WHERE
manh_dist(tjoin1.fv,tjoin2.fv)<=8000
) joinresult INNER JOIN cophirphoto500k lp
ON (joinresult.photoid = lp.photoid)
WHERE to_char(lp.dateposted, 'YYYY/MM/DD') >= '2002/01/01' AND to_char(lp.dateposted, 'YYYY/MM/DD') <= '2006/11/01'
AND manh_dist(joinresult.fv, (SELECT cfv_sel.fv FROM cophirfv500k cfv_sel WHERE id=2))<=5500;
Has this execution plan:
In another attempt, the system stops using the index on the condition manh_dist(joinresult.fv, (SELECT cfv_sel.fv FROM cophirfv500k cfv_sel WHERE id=2))<=5500. But it does not use it on the other one, as it should be.
SELECT /*+ INDEX(#subq tjoin1) */ count(*)
FROM
(SELECT /*+ qb_name(subq) */ tjoin1.fv, tjoin1.photoid
FROM minfv tjoin2, cophirfv500k tjoin1
WHERE
manh_dist(tjoin1.fv,tjoin2.fv)<=8000
) joinresult INNER JOIN cophirphoto500k lp
ON (joinresult.photoid = lp.photoid)
WHERE to_char(lp.dateposted, 'YYYY/MM/DD') >= '2002/01/01' AND to_char(lp.dateposted, 'YYYY/MM/DD') <= '2006/11/01'
AND manh_dist(joinresult.fv, (SELECT cfv_sel.fv FROM cophirfv500k cfv_sel WHERE id=2))<=5500;
The new execution plan is:
Oracle does use index when I call this block separately.
SELECT tjoin1.fv, tjoin1.photoid
FROM minfv tjoin2, cophirfv500k tjoin1
WHERE
manh_dist(tjoin1.fv,tjoin2.fv)<=8000;
The execution plan it builds is:
The system is not capable of gathering the right statistcs, that is the why I am trying to do it.
How can I force the compiler to use the index on the condition manh_dist(tjoin1.fv,tjoin2.fv)<=8000, in the complex query ?
Hope someone can help.
Thanks in advance!

SQL Server query issues

We have a SQL Server 2012 database with our live project including multiple tables and records, Basically We are facing a problem with SQL queries on a table where two same SQL queries. The first SQL query is taking less execution time and second SQL query is getting tremendously slow to execute.
I don't know why it is happening someone could help me to solve this problem?
Our two queries are given below....
First query (taking so much time to execute):
SELECT * FROM (SELECT TOP 10 TrackerResponse.EventName,TrackerResponse.ReceiveTime,ISNull(TrackerResponse.InputStatus,0) AS InputStatus,
TrackerResponse.Latitude,TrackerResponse.Longitude,TrackerResponse.Speed,
TrackerResponse.TrackerID,TrackerResponse.OdoMeter,TrackerResponse.Direction,
UserCar.CarNo FROM TrackerResponse
INNER JOIN UserCar ON (UserCar.TrackerID = TrackerResponse.TrackerID)
WHERE (TrackerResponse.EventName IS NOT NULL AND TrackerResponse.EventName<>'')
AND TrackerResponse.TrackerID = 112 Order By ID DESC) AS Events)
Second query (taking less execution time):
SELECT * FROM (SELECT TOP 10 TrackerResponse.EventName,TrackerResponse.ReceiveTime,ISNull(TrackerResponse.InputStatus,0) AS InputStatus,
TrackerResponse.Latitude,TrackerResponse.Longitude,TrackerResponse.Speed,
TrackerResponse.TrackerID,TrackerResponse.OdoMeter,TrackerResponse.Direction,
UserCar.CarNo FROM TrackerResponse
INNER JOIN UserCar ON (UserCar.TrackerID = TrackerResponse.TrackerID)
WHERE (TrackerResponse.EventName IS NOT NULL AND TrackerResponse.EventName<>'')
AND TrackerResponse.TrackerID = 56 Order By ID DESC) AS Events
I see Both queries are similar with an exception of tracker id..so my best guess would be ,this query might be a victim of Parameter sniffing..
Try using Option(Recompile) like below to see if this is the cause and follow article referred in above link for resolution
SELECT * FROM (SELECT TOP 10 TrackerResponse.EventName,TrackerResponse.ReceiveTime,ISNull(TrackerResponse.InputStatus,0) AS InputStatus,
TrackerResponse.Latitude,TrackerResponse.Longitude,TrackerResponse.Speed,
TrackerResponse.TrackerID,TrackerResponse.OdoMeter,TrackerResponse.Direction,
UserCar.CarNo FROM TrackerResponse
INNER JOIN UserCar ON (UserCar.TrackerID = TrackerResponse.TrackerID)
WHERE (TrackerResponse.EventName IS NOT NULL AND TrackerResponse.EventName<>'')
AND TrackerResponse.TrackerID = 56 Order By ID DESC
option(recompile)
AS Events)