2007年03月2日

處理sql沒有走index的流程

由oracle的em中看到sql沒有走index,但已有建立查尋相關的index所需的欄位了,但oracle就是用full table scan
以下是我處理的流程:

1、先查看相關的table上面有的index為何跟index的欄位為何跟index是否為有效
SQL>select * from user_ind_columns where index_name in (select index_name from user_indexes where table_name = 'table_name' ') order by table_name;
2、因為我前端都是jdbc來連oracle的,所以我建立一個額外的使用者來好觀查sql 的執行計畫
CREATE USER "SQLTRACE" PROFILE "DEFAULT" IDENTIFIED BY "*******" DEFAULT TABLESPACE "USERS" ACCOUNT UNLOCK
GRANT CREATE SESSION TO "SQLTRACE"
GRANT UNDER ANY TABLE TO "SQLTRACE"
GRANT "CONNECT" TO "SQLTRACE"
GRANT "RESOURCE" TO "SQLTRACE"
GRANT SELECT ANY TABLE TO "SQLTRACE"
3、寫一隻jsp,以測試前端ap連入oracle的環境
<%@ page contentType="text/html;charset=big5"%>
<%@ page import="java.sql.*,java.util.*;"%>
<html>
<body>

<%
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url="jdbc:oracle:thin:@testdb:1521:testdb";
String user="sqltrace";
String password="sqltrace";
Connection conn= DriverManager.getConnection(url,user,password);
try {
Thread.sleep(60*1000); //因為我要得到sid跟serial 的值,所以我要暫停一下
}
catch(InterruptedException e) {
e.printStackTrace();
}

//Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
//String sql="select count(*) from apmobile.t_user_login l where l.context='/pet' and l.last_access>(sysdate-(1/24)) and exists(select guid from apmobile.t_user where context=l.context and guid=l.guid and member=1)";
//ResultSet rs=stmt.executeQuery(sql);

PreparedStatement ps = conn.prepareStatement("select count(*) from apmobile.t_user_login l where l.context=? and l.last_access>? and exists(select guid from apmobile.t_user where context=l.context and guid=l.guid and member=?)");
ps.setString(1, "/pet");
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE,-30);
Timestamp now = new Timestamp(cal.getTimeInMillis());
ps.setTimestamp(2,now);
ps.setInt(3,1);
ResultSet rs = ps.executeQuery();

if (rs.next()) { %>
count:<%=rs.getInt(1)%>
<%}
rs.close();
rs = null;

// stmt.close();
// stmt = null;

ps.close();
ps = null;

conn.close();
conn = null;
%>
</body>
</html>
4、執行sql trace所需的指令
//得到使用者的sid跟serial
SQL> select sid,serial# from v$session where username='SQLTRACE';
//把使用者執行的sql相關資料記錄起來
SQL> execute dbms_system.set_sql_trace_in_session(sid,serial#,true);
//如使用者的session沒有關畢的話,可以強迫關畢
SQL> alter system kill session(sid,serial#);
5、產生報表(預設值是在 admin/udump/)
tkprof 記錄檔.trc 報表檔

相關的資料請上google查尋tkprof、dbms_system.set_sql_trace_in_session

Posted by my_work at 樂多Roodo! │15:32 │回應(0)引用(0)DB
樂多分類:網路/3C 共同主題:Oracle 工具:編輯本文
Ads by Roodo! 

引用URL

http://cgi.blog.roodo.com/trackback/2792527