At this point there's not enough info to know for sure what the issue is.
NOTE: The following may (not) apply in your situation ... hard to tell since there's no mention of them in your post ... so fwiw ...
- You're monitoring syslogshold but we don't know if that 2+hour long transaction is a single INSERT/UPDATE/DELETE statement, or a batch of queries wrapped in a 'begin/commit tran' pair. If the latter, eg:
begin tran <<<---- shows up in syslogshold
insert...
update...
select...
insert...
update... <<<--- grab query plan
select...
commit tran <<<--- closes out syslogshold record
... the 2nd update may in fact run quickly, but what you really want to do is find out which of the earlier queries ran long and why.
- You've re-run a query that runs within a couple minutes, but we don't know if that query is being run multiple times within a loop when executed as part of your report processing. For example, while a single query may 'only' take 2 minutes to run, if you're executing that query 100 times within a loop (and the loop is within a 'begin/commit tran' pair) then the entire looping process will show up as a 200+ minute entry in syslogshold.
- You've stated the stored proc query's plan is the same as when the query is run via isql; you haven't mentioned if the both queries were working with the same volume of data; we also don't know if the proc's query was having to wait for disk IOs while the isql query had the benefit of having most of its data already in cache (ie, no long waits for disk IOs).
When you take the query plan snapshot of the proc's query I'd suggest you also grab a snapshot of monProcessObject for the SPID (this will give you an idea of logical/physical IOs for each table referenced in the query plan). And for the isql session I'd run the query with 'set statistics io,time on' to get a count of logical/physical IOs for each table accessed by the query. Objective is to see if you are getting a comparable volume of logical/physical IOs for each query.
NOTE: Keep in mind that monProcessObject will give you a snapshot of IOs up to that point in time; net result is that you may need to take multiple snapshots while the query is running so that when the query completes the last snapshot will be closest to the actual number of IOs performed.
NOTE: To insure you get accurate IO details for the report you could add 'set showplan on/set statistics io,time on' to the report process script ... assuming the extra output from said 'set' commands won't compromise the final output from your report process.
- While you've mentioned that the query plans (stored proc vs isql) are the same, I'd want to run a 'diff' on the 2 plans just to be 100% sure they really are exact.
NOTE: I have no idea what your experience level is with ASE and reading query plans, but it can be very easy to take a cursory glance at a couple query plans (especially really long, multi-page query plans) and declare them the same when in reality there are some subtle differences (eg, merge join vs NL join, join order, different index usage, index referenced by column vs index referenced by scan, etc). And yes, this can happen to folks (me included) with years of ASE P&T under their belts.