How to get execution stats for a PL/SQL function? - java

I have a PL/SQL function that is called from our Java code.
I have the SQL_ID of the PL/SQL function execution and I have access to V$ views on my read-only DB user. The query takes quite some time to execute? Is there a way to profile the PL/SQL function execution to check where exactly the execution is stuck?
I know how to do this for SQL queries with V$SQL, V$ACTIVE_SESSION_HISTORY and V$SESSION_LONGOPS, but I am unable to figure out how to do this for PL/SQL code.
The PL/SQL function takes 4 minutes to execute, so I can execute quite a few V$ queries manually in that time. What V$ views should I check to find a line in the execution plan/function? Is this even possible?

Maybe you can use DBMS_PROFILER for your problem. But if you want to use this method, you have to install some infrastructure.
I don't want to describe the process how to install "proftab.sql", this link shows how it works.
It also shows some quick examples how to trace a specific function.
I can provide my version of the analyze-query after some testing:
select ppr.runid,
ppr.run_comment1,
decode(nvl(ppd.total_occur, 0), 0, 0, ppd.total_time / ppd.total_occur / 1000000) as Avg_msek,
ppd.total_time / 1000000 totaltime_msek,
ppd.total_occur,
uc.name,
uc.line,
uc.text as Source
from plsql_profiler_data ppd, plsql_profiler_units ppu, user_source uc, plsql_profiler_runs ppr
where ppd.runid = ppu.runid
and ppu.runid = ppr.runid
-- and ppr.run_comment1 = 'MYTEST' --show only a specific testrun
-- and ppr.runid = (select max(runid) from plsql_profiler_runs) /*to get the last run*/
and ppd.unit_number = ppu.unit_number
and ppu.unit_name = uc.name
and ppd.line#(+) = uc.line
and uc.type in ('PACKAGE BODY', 'TYPE BODY')
--order by uc.name, uc.line; --Show all code by line
--order by totaltime_msek desc; --Sort by slowest lines
order by total_occur desc, avg_msek desc --Sort by calls and slowest ones

Related

Mysql Get_Lock and Release_Lock functions taking long time

We are trying to use MYSQL's locking function Get_Lock and Release_Lock in our spring java application . The code we are using is defined in a procedure for both seperately which simply invoke from our java code .The queries inside the proc are given below .
We have been monitoring the execution time of these functions and found that at times it takes a millisecond to execute but at other times , this takes around 400 to 600 ms . I have tried the following approaches but there hasn't been much of a difference :
1. Use "Do" in place of select with these functions .
2. Using an int data type of the key which we are using as lock string .
3. Decreasing the length of lock string .
I am using a timeout of 0 to avoid connections being locked.
Can anyone please suggest me a way to optimize this .Is there a way of optimizing innodb buffer pool or something related to these configurations .
Please do let me know if any other input is required from my end .
Please find below some proc code and stats for your reference .
Current Mysql Code :
Proc :
get_Name_lock:
-- Using select
Select get_lock(Name,0) into c_Name_flag;
-- Using Do
Do get_lock(Name,0) ;
Proc :
release_Name_lock :
-- Using select
Select release_lock(Name) into c_Name_flag;
-- Using Do
Do release_lock(Name);
Request rate : (around)10 requests/sec .
Mysql Version : 5.7.19-log

tracing a sql server stored procedure not appearing in profiler

I am trying to trace the execution of a sql server stored procedure that gets executed from within a large java application. I first changed the stored procedure to complete the task I needed to do and I tested within sql server and it worked fine, with all triggers working too. However, when I apply the changes and run the code it seems like the changed stored procedure is not executed but just the original version. I tried to use profile to trace the execution but the weird thing is that it does not appear. Again testing the inserts manually does then show the procedure in profiler.
I tried to trace the code that implements this procedure, found it and wrote some trace comments to tag the execution but again the class trace commenting does not occur. As if the class does not get called. I have added the procedure just in case someone sees a fault but like I said it works fine testing in SQL server.
BEGIN
DECLARE #KeepStoreLingerTime int
DECLARE #KeepDeleteLingerTime int
DECLARE #StoreActionID int
DECLARE #insertedID int;
IF #TimeToExecute IS NULL
BEGIN
SELECT #KeepStoreLingerTime = [Value] FROM SystemProperty WHERE [Name] = 'KeepStoreLingerTimeInMinutes'
SELECT #KeepDeleteLingerTime = [Value] FROM SystemProperty WHERE [Name] = 'KeepDeleteLingerTimeInMinutes'
IF (#KeepDeleteLingerTime >= #KeepStoreLingerTime) SET #KeepStoreLingerTime = #KeepDeleteLingerTime+1
SET #TimeToExecute = dateadd(mi, #KeepStoreLingerTime, getutcdate())
END
SELECT #StoreActionID = [ID] FROM StoreActionQueue
WHERE Parameter=#Parameter AND StorageRuleID=#StorageRuleID AND StoreFlags=#StoreFlags
IF #StoreActionID IS NOT NULL AND #StoreFlags != 11
BEGIN
UPDATE StoreActionQueue SET FilterID = #FilterID WHERE [ID] = #StoreActionID
END
ELSE
BEGIN
INSERT INTO StoreActionQueue (TimeToExecute, Operation, Parameter, StorageRuleID, FilterID, StoreFlags)
SELECT #TimeToExecute, #Operation, #Parameter, #StorageRuleID, #FilterID, #StoreFlags FROM Call WHERE [ID]=#Parameter AND Active=0
AND (OnlineCount>0 OR OnlineScreenCount>0 OR (Flags&POWER(2,26)=POWER(2,26))) --bit26 indicates META-DATA-ONLY
---- INSERT if a row is successfully inserted
IF ##ROWCOUNT > 0
IF #StoreFlags = 11
BEGIN
INSERT INTO StoreActionQueue (TimeToExecute, Operation, Parameter,
StorageRuleID, FilterID, StoreFlags)
SELECT DATEADD(mi, 2, GETUTCDATE()), #Operation, #Parameter,
#StorageRuleID, #FilterID, 9 FROM Call
WHERE [ID]=#Parameter AND Active=0
END
END
END
Is there a way to log anything from lets say within the procedure to a file? In java (eclipse) other than looking at call hierarchy etc. is there a suggestion on how to match where the class gets called.
public class ProcessingController extends TimeController implements
TimeObserver {

Neo4j slow cypher query in embedded mode

I have a huge graphdatabase with authors, which are connected to papers and papers a connected to nodes which contains meta information of the paper.
I tried to select authors which match a specific pattern and therefore I executed the following cypher statement in java.
String query = "MATCH (n:AUTHOR) WHERE n.name =~ '(?i).*jim.*' RETURN n";
db.execute(query);
I get a resultSet with all "authors" back. But the execution is very slow. Is it, because Neo4j writes the result into the memory?
If I try to find nodes with the Java API, it is much faster. Of course, I am only able to search for the exact name like the following code example, but it is about 4 seconds faster as the query above. I tested it on a small database with about 50 nodes, whereby only 6 of the nodes are authors. The six author are also in the index.
db.findNodes(NodeLabel.AUTHOR, NodeProperties.NAME, "jim knopf" );
Is there a chance to speed up the cypher? Or a possiblity to get all nodes via Java API and the findNodes() method, which match a given pattern?
Just for information, I created the index for the name of the author in java with graph.schema().indexFor(NodeLabel.AUTHOR).on("name").create();
Perhaps somebody could help. Thanks in advance.
EDIT:
I run some tests today. If I execute the query PROFILE MATCH (n:AUTHOR) WHERE n.name = 'jim seroka' RETURN n; in the browser interface, I have only the operator NodeByLabelScan. It seems to me, that Neo4j does not automatic use the index (Index for name is online). If I use a the specific index, and execute the query PROFILE MATCH (n:AUTHOR) USING INDEX n:AUTHOR(name) WHERE n.name = 'jim seroka' RETURN n; the index will be used. Normally Neo4j should use automatically the correct index. Is there any configuration to set?
I also did some testing in the embedded mode again, to check the performance of the query in the embedded mode. I tried to select the author "jim seroka" with db.findNode(NodeLabel.AUTHOR, "name", "jim seroka");. It works, and it seems to me that the index is used, because of a execution time of ~0,05 seconds.
But if I run the same query, as I executed in the interface and mentioned before, using a specific index, it takes ~4,9 seconds. Why? I'm a little bit helpless. The database is local and there are only 6 authors. Is the connector slow or is the creation of connection wrong? OK, findNode() does return just a node and execute a whole Result, but four seconds difference?
The following source code should show how the database will be created and the query is executed.
public static GraphDatabaseService getNeo4jDB() {
....
return new GraphDatabaseFactory().newEmbeddedDatabase(STORE_DIR);
}
private Result findAuthorNode(String searchValue) {
db = getNeo4jDB();
String query = "MATCH (n:AUTHOR) USING INDEX n:AUTHOR(name) WHERE n.name = 'jim seroka' RETURN n";
return db.execute(query);
}
Your query uses a regular expression and therefore is not able to use an index:
MATCH (n:AUTHOR) WHERE n.name =~ '(?i).*jim.*' RETURN n
Neo4j 2.3 introduced index supported STARTS WITH string operator so this query would be very performant:
MATCH (n:Author) WHERE n.name STARTS WITH 'jim' RETURN n
Not quite the same as the regular expression, but will have better performance.

SPARQL Query Execution time using Jena on a Virtuoso service

So I am using a Virtuoso SPARQL endpoint and I am using Jena to query it. I use QueryFactory and QueryExecution to create a SPARQL query :
Query query = QueryFactory.create(sparqlQueryString1);
QueryExecution qexec = QueryExecutionFactory.sparqlService("http://localhost:8890/sparql", query);
ResultSet results = qexec.execSelect();
Now I want to calculate the time taken to run this query. How does one find such a time using Jena on Virtuoso? Is that possible? Obviously I did look at functions like getTimeOut1() and getTimeOut2(). They don't seem to be giving me any good direction. As a hack I tried using Java's inbuilt System.currentTimeMillis(), However I am not sure if that is the right way. Any pointers as to how I can find execution time would be appreciated!
Results come back as a stream so the timing needs to span from just before qexec.execSelect() to just after the app finished handling the results, not just call execSelect.
Timer timer = new Timer() ;
timer.startTimer() ;
ResultSet results = qexec.execSelect();
ResultSetFormatter.consume(results) ;
long x = timer.finishTimer() ; // Time in milliseconds.
It's not clear whether you want to time the full round-trip, or just the time Virtuoso spends on things...
Virtuoso 7 lets you get the compilation (query plan) and execution time of a query using the profile function.
You can also enable general query logging and profiling using the prof_enable function.

Long running queries MySQL with Java

I'm using MySQL 5.1, Apache Tomcat 7, MyBatis 3.1
I have a method with code like this:
for( Order o : orders) {
List<Details> list = getDetails(o);
//Create PDF report ...
}
Where getDetails is a method that executes a stored procedure that takes some time to execute ( 1 to 2 seconds), The problem here is that I have many orders (near 4000) and I need to execute this method to process every order, and when I hit that method, the CPU usage of the MySQL process goes up to 90 - 100%
Is that normal?, Do I need to use Thread.sleep() after getDetails if executed?, Or do I need to do some modifications to my query?,

Categories

Resources