绑定参数的SQL

Java代码 复制代码
  1. select sql_text ,sharable_mem from v$sql where sharable_mem > '100000' order by sharable_mem ;   
select sql_text ,sharable_mem from v$sql where sharable_mem > '100000' order by sharable_mem ; 


上面的sql语句是查询shared pool中占用内存超过100K的sql语句。

        共享池主要由库缓冲区(共享SQL区和PL/SQL区)和数据字典缓冲区组成。

     select * from v$sgastat; --显式SGA的状态信息。

If the SHARED_POOL_SIZE is large enough, most ORA-04031 errors are a result of  dynamic sql fragmenting the shared pool.  This can be caused by:

        o Not sharing SQL
        o Making unnecessary parse calls (soft)
        o Not using bind variables

ava代码 复制代码

  1. select * from table_name where id = 1;    
  2. select * from table_name where id = 2;   
select * from table_name where id = 1; 
select * from table_name where id = 2; 

每次查询都要进行sql语句的执行解析,并且每个sql都会分配一个区域来存放sql解析后的二进制可执行代码。试想,要是id不同的10万个sql呢?Oracle就会分配10万个sql区域来分别存放10万个这样的id不同的sql语句。对于一个数据库驱动的Web网站这样情况下,SGA开的再大,也会很快被耗尽share pool的,最后报一个ORA-4031错误。数据库就连接不上了,只好重起。

正确的写法应该是:

Java代码 复制代码
  1. PreparedStatement pstmt = conn.prepareStatement("select * from table_name where id = ?");;    
  2.   
  3. pstmt.setInt(1,1);;    
  4. rset = pstmt.executeQuery();;    
  5. ...    
  6. pstmt.setInt(1,2);;    
  7. rset = pstmt.executeQuery();;   
PreparedStatement pstmt = conn.prepareStatement("select * from table_name where id = ?");; 

pstmt.setInt(1,1);; 
rset = pstmt.executeQuery();; 
... 
pstmt.setInt(1,2);; 
rset = pstmt.executeQuery();; 


这样Oracle数据库就知道你实际上用的都是同一条sql语句,会以这样的形式:
select * from table_name where id = :1
解析执行后存放在sql区域里面,当以后再有一样的sql的时候,把参数替换一下,就立刻执行,不需要再解析sql了。既加快了sql执行速度,也不会占有过多SGA的share pool。

你可能感兴趣的:(oracle,sql,Web)