程序运行起来之后,发现比较慢,这就是个性能问题。性能问题常常需要追踪到sql的路线问题,本文就想谈谈在oracle上面sql的追踪方式。
软件的架构一般为: Clients->Application Servers->Database Servers, 其中客户端就是大量的用户,它们经过TCP(其上的协议可以为:HTTP, RMI, IIOP,Texedo, CICS等)连接到Application Servers;Application Servers在于千兆的速度与数据库进行连接(传输的则为SQL),Application Servers可以是一个集群环境; 数据库是整个的即时,它同样可以有集群来构成,Oracle提供的RAC技术就是用来做集群的。
Application Servers端:通过ps -ef | grep *, 查处其进程id。
Database: Oracle的transaction隐式的开始于发起的修改数据的sql语句,结束于显示的提交、回滚、SAVEPOINT、ROLLBACK TO <SAVEPOINT>、SET Transaction.
desc v$transaction; select addr from v$transaction;--从中可以看出已经存在了一个transaction, 当客户端显示的commit之后,这条记录已经不存在了。
v$session --当前有多少用户连接到了oracle服务区, desc v$session; select sid, username, status from v$session;--查出来,其中username为空的, 为oracle自己的后台进程, 重点关注非空的用户(在客户端用show user显示发起端的用户是哪个)。
在linux上面使用netstat查看, 使用
netstat -anp | more可以查出PID、本地地址local address和远端的socket地址(在windows上用ipconfig可以看到自己的ip地址, windows的地址正好就是linux上面netstat -anp查出的远端地址foreign address; 同时在windows上面,可以使用
netstat -b找出windows上发起相应ip:port的进程究竟是哪一个, 它的本地地址就是自己,它的远端地址就是linux上面的前面提到的本地地址, 同时可以看出windows上面进程的PID和进程名字, 也可以通过任务管理中pid查出程序名)。 通过ps -ef | grep PID, 可以知道这个进程就是负责和远端连接的dedicated server进程。
![sql关系](../p_w_upload/200912/200912211261404161870.jpg)
v$transaction --服务器上有哪些transaction
v$process --transaction是属于哪个客户端的用户,则查v$process
v$sql --当前正在执行的sql语句
select addr,
ses_addr from v$transaction; --查找出当前正在执行的transaction; 通过查出来的ses_addr值, 在v$session中去查找, 使用select
saddr,sid,
paddr, username, status from v$session; 通过select saddr, sid, paddr, username, status from v$session查找出是哪个进程发起的这个transaction。 通过刚才查到的paddr(在v$process中叫addr, 见上图)查找表v$process, 通过语句select
addr, spid from v$process查出spid对应的进程号。 通过进程号,查出相应的进程信息(ps -ef | grep 进程号(即spid)), 还需要通过
netstat -anp查出其具体的进程信息(包括本地地址和远端地址)。 使用select sid,
prev_sql_addr, username, status from v$session找出其prev_sql_addr关联到v$sql的
address字段, 通过select
sql_text, address from v$sql where address='***'; (其中***代表刚才v$session中查到的prev_sql) 此时, 你就可以看到你刚才在客户端执行的sql语句就出现在你的面前。
一些简化的连接可以加快定位问题: select sid, username, process, program from v$transaction t, v$session s where t.ses_addr=s.saddr;
总结如下:
col sql_text format a40;
(1)直接查出执行的SQL:
select sql_text, address from v$sql where address in (select s.prev_sql_addr from v$session s, v$transaction t where t.ses_addr=s.saddr);
或者 select sql_text as "执行的SQL", address from v$sql where address in (select s.prev_sql_addr from v$session s, v$transaction t where t.ses_addr=s.saddr);
(2) 查出session与transaction的关联:select s.saddr,s.sid, s.paddr, s.username, s.status, s.prev_sql_addr from v$session s, v$transaction t where t.ses_addr=s.saddr;
转载于:https://blog.51cto.com/tianya23/247312