I’ve been troubleshooting a major performance issue in a SL4 application that utilizes the Entity Framework and a WCF Data Service to query some simple, mid-sized (~10M records) tables, and I’ve finally made some progress.
A query sent from the data service for either 100 rows or a simple filter that returns >100 rows for a simple table takes 5 minutes to return anything at all. The same query run in SQL Developer returns the first 50 rows virtually instantaneously.
Examining the trace logs of these queries reveals the exact same execution plan and overall elapsed times. The difference is that nothing is returned to the data service until the entire query is executed, whereas SQL developer gets the first 100 right away.
I thought paging might be the solution: config.SetEntitySetPageSize("*", 5);
But the trace log shows the first batch of rows being grabbed immediately before Oracle moves on to the next statement:
.... SIMPLE SQL QUERY ...
PARSE #2:c=78000,e=100606,p=0,cr=3,cu=0,mis=1,r=0,dep=0,og=1,tim=205746975549
EXEC #2:c=0,e=226,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=205747109728
FETCH #2:c=46800,e=42299,p=0,cr=7134,cu=0,mis=0,r=20,dep=0,og=1,tim=205747229491
=====================
PARSING IN CURSOR #3 len=402 dep=1 uid=0 oct=3 lid=0 tim=205747256638 hv=3607805727 ad='18f64810'
select parttype, partcnt, partkeycols, flags, defts#, defpctfree, defpctused, definitrans, defmaxtrans, deftiniexts, defextsize, defminexts, defmaxexts, defextpct, deflists, defgroups, deflogging, spare1, mod(spare2, 256) subparttype, mod(trunc(spare2/256), 256) subpartkeycols, mod(trunc(spare2/65536), 65536) defsubpartcnt, mod(trunc(spare2/4294967296), 256) defhscflags from partobj$ where obj# = :1
END OF STMT
At the end of the trace log, the rest of the rows are fetched:
....
END OF STMT
EXEC #3:c=0,e=15,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=205747262472
FETCH #3:c=0,e=24,p=0,cr=3,cu=0,mis=0,r=1,dep=1,og=4,tim=205747263090
FETCH #2:c=78001,e=81705,p=0,cr=14014,cu=0,mis=0,r=40,dep=0,og=1,tim=205747515725
FETCH #2:c=171601,e=162799,p=0,cr=27712,cu=0,mis=0,r=80,dep=0,og=1,tim=205747887738
FETCH #2:c=343202,e=328508,p=0,cr=55584,cu=0,mis=0,r=160,dep=0,og=1,tim=205748620538
...
*** 2012-03-21 19:34:10 2012
XCTEND rlbk=0, rd_only=1
as before, and still nothing is returned to the data service until they are all FETCH’ed.
The question is: how do you make Oracle send the first page of results back to the data service immediately?
a) Your query does not ask for only 100 rows!
b) You have no ORDER BY so how do you define the rows anyway?
Some ways of Oracle:
/* FIRST_ROWS */ Hint in your query will return first rows as early as it can but will still return the entire set.
WHERE ROWNUM < 100
will stop sthe query after 100 rows are emitted. You need an ORDER BY for this to make sense.
Ask Tom