This is a great quick script to identify those statements taking the most time over a small time window. It’s a good “911” type script. This will print those statements that have a total elapsed execution time of the percentage of time passed on the command line.
If you name the content of the file below sqldiff.py, you can call it as follows:
#this will print only those statements that run for at least 2.5 seconds during a five second window sqldiff.py 5 50
The script content is below.
#!/usr/local/bin/python import cx_Oracle, sys, time con = cx_Oracle.connect("username/password@dbhost:dbport/dbservice") cursor = con.cursor() first = dict() second = dict() cursor.execute(""" select sql_id,sum(executions),sum(elapsed_time) from gv$sql where (lower(sql_text) like 'select%' or lower(sql_text) like 'delete%' or lower(sql_text) like 'update%' or lower(sql_text) like 'merge%' or lower(sql_text) like 'insert%') group by sql_id """) for r in cursor: first[r[0]] = str(r[1]) + "~" + str(r[2]) time.sleep(int(sys.argv[2])) cursor.execute("select sql_id,sum(executions),sum(elapsed_time) from gv$sql group by sql_id") for r in cursor: second[r[0]] = str(r[1]) + "~" + str(r[2]) for i in first: if i in second: tmp = first[i].split("~") tmp2 = second[i].split("~") if int(tmp2[1]) - int(tmp[1]) > int(int(sys.argv[2]) * 1000000 * (float(sys.argv[3]) / 100)): cursor.execute("select sql_fulltext from gv$sql where sql_id = :1 and rownum = 1",[i]) for r in cursor: sql = r[0] print "SQL_ID".ljust(30,"."),i print "SQL_TEXT".ljust(30,"."),sql print "EXECUTIONS".ljust(30,"."),int(tmp2[0]) - int(tmp[0]) avg = (int(tmp2[1]) - int(tmp[1]))/1000/(int(tmp2[0]) - int(tmp[0])) if int(tmp2[0]) - int(tmp[0]) > 0 else (int(tmp2[1]) - int(tmp[1]))/1000 print "MILLIS_PER_EXEC".ljust(30,"."),avg print "-".ljust(80,"-")