[ Index ]

PHP Cross Reference of MantisBT

title

Body

[close]

/library/adodb/perf/ -> perf-oci8.inc.php (source)

   1  <?php
   2  /* 
   3  V5.11 5 May 2010   (c) 2000-2010 John Lim (jlim#natsoft.com). All rights reserved.
   4    Released under both BSD license and Lesser GPL library license. 
   5    Whenever there is any discrepancy between the two licenses, 
   6    the BSD license will take precedence. See License.txt. 
   7    Set tabs to 4 for best viewing.
   8    
   9    Latest version is available at http://adodb.sourceforge.net
  10    
  11    Library for basic performance monitoring and tuning 
  12    
  13  */
  14  
  15  // security - hide paths
  16  if (!defined('ADODB_DIR')) die();
  17  
  18  class perf_oci8 extends ADODB_perf{
  19  
  20      var $noShowIxora = 15; // if the sql for suspicious sql is taking too long, then disable ixora
  21      
  22      var $tablesSQL = "select segment_name as \"tablename\", sum(bytes)/1024 as \"size_in_k\",tablespace_name as \"tablespace\",count(*) \"extents\" from sys.user_extents 
  23         group by segment_name,tablespace_name";
  24       
  25      var $version;
  26      
  27      var $createTableSQL = "CREATE TABLE adodb_logsql (
  28            created date NOT NULL,
  29            sql0 varchar(250) NOT NULL,
  30            sql1 varchar(4000) NOT NULL,
  31            params varchar(4000),
  32            tracer varchar(4000),
  33            timer decimal(16,6) NOT NULL
  34          )";
  35      
  36      var $settings = array(
  37      'Ratios',
  38          'data cache hit ratio' => array('RATIOH',
  39              "select round((1-(phy.value / (cur.value + con.value)))*100,2) 
  40              from v\$sysstat cur, v\$sysstat con, v\$sysstat phy
  41              where cur.name = 'db block gets' and
  42                    con.name = 'consistent gets' and
  43                    phy.name = 'physical reads'",
  44              '=WarnCacheRatio'),
  45          
  46          'sql cache hit ratio' => array( 'RATIOH',
  47              'select round(100*(sum(pins)-sum(reloads))/sum(pins),2)  from v$librarycache',
  48              'increase <i>shared_pool_size</i> if too ratio low'),
  49              
  50          'datadict cache hit ratio' => array('RATIOH',
  51          "select      
  52             round((1 - (sum(getmisses) / (sum(gets) +          
  53              sum(getmisses))))*100,2)
  54          from  v\$rowcache",
  55          'increase <i>shared_pool_size</i> if too ratio low'),
  56          
  57          'memory sort ratio' => array('RATIOH',
  58          "SELECT ROUND((100 * b.VALUE) /DECODE ((a.VALUE + b.VALUE), 
  59         0,1,(a.VALUE + b.VALUE)),2)
  60  FROM   v\$sysstat a, 
  61         v\$sysstat b
  62  WHERE  a.name = 'sorts (disk)'
  63  AND    b.name = 'sorts (memory)'",
  64      "% of memory sorts compared to disk sorts - should be over 95%"),
  65  
  66      'IO',
  67          'data reads' => array('IO',
  68          "select value from v\$sysstat where name='physical reads'"),
  69      
  70      'data writes' => array('IO',
  71          "select value from v\$sysstat where name='physical writes'"),
  72      
  73      'Data Cache',
  74      
  75          'data cache buffers' => array( 'DATAC',
  76          "select a.value/b.value  from v\$parameter a, v\$parameter b 
  77              where a.name = 'db_cache_size' and b.name= 'db_block_size'",
  78              'Number of cache buffers. Tune <i>db_cache_size</i> if the <i>data cache hit ratio</i> is too low.'),
  79          'data cache blocksize' => array('DATAC',
  80              "select value from v\$parameter where name='db_block_size'",
  81              '' ),            
  82      
  83      'Memory Pools',
  84          'Mem Max Target (11g+)' => array( 'DATAC',
  85          "select value from v\$parameter where name = 'memory_max_target'",
  86              'The memory_max_size is the maximum value to which memory_target can be set.' ),
  87      'Memory target (11g+)' => array( 'DATAC',
  88          "select value from v\$parameter where name = 'memory_target'",
  89              'If memory_target is defined then SGA and PGA targets are consolidated into one memory_target.' ),
  90          'SGA Max Size' => array( 'DATAC',
  91          "select nvl(value,0)/1024.0/1024 || 'M' from v\$parameter where name = 'sga_max_size'",
  92              'The sga_max_size is the maximum value to which sga_target can be set.' ),
  93      'SGA target' => array( 'DATAC',
  94          "select nvl(value,0)/1024.0/1024 || 'M'  from v\$parameter where name = 'sga_target'",
  95              'If sga_target is defined then data cache, shared, java and large pool size can be 0. This is because all these pools are consolidated into one sga_target.' ),
  96      'PGA aggr target' => array( 'DATAC',
  97          "select value from v\$parameter where name = 'pga_aggregate_target'",
  98              'If pga_aggregate_target is defined then this is the maximum memory that can be allocated for cursor operations such as sorts, group by, joins, merges. When in doubt, set it to 20% of sga_target.' ),
  99      'data cache size' => array('DATAC',
 100              "select value from v\$parameter where name = 'db_cache_size'",
 101              'db_cache_size' ),
 102          'shared pool size' => array('DATAC',
 103              "select value from v\$parameter where name = 'shared_pool_size'",
 104              'shared_pool_size, which holds shared sql, stored procedures, dict cache and similar shared structs' ),
 105          'java pool size' => array('DATAJ',
 106              "select value from v\$parameter where name = 'java_pool_size'",
 107              'java_pool_size' ),
 108          'large pool buffer size' => array('CACHE',
 109              "select value from v\$parameter where name='large_pool_size'",
 110              'this pool is for large mem allocations (not because it is larger than shared pool), for MTS sessions, parallel queries, io buffers (large_pool_size) ' ),
 111  
 112          'pga buffer size' => array('CACHE',            
 113              "select value from v\$parameter where name='pga_aggregate_target'",
 114              'program global area is private memory for sorting, and hash and bitmap merges - since oracle 9i (pga_aggregate_target)' ),
 115  
 116          'dynamic memory usage' => array('CACHE', "select '-' from dual", '=DynMemoryUsage'),
 117          
 118          'Connections',
 119          'current connections' => array('SESS',
 120              'select count(*) from sys.v_$session where username is not null',
 121              ''),
 122          'max connections' => array( 'SESS',
 123              "select value from v\$parameter where name='sessions'",
 124              ''),
 125  
 126      'Memory Utilization',        
 127          'data cache utilization ratio' => array('RATIOU',
 128              "select round((1-bytes/sgasize)*100, 2)
 129              from (select sum(bytes) sgasize from sys.v_\$sgastat) s, sys.v_\$sgastat f
 130              where name = 'free memory' and pool = 'shared pool'",
 131          'Percentage of data cache actually in use - should be over 85%'),
 132          
 133          'shared pool utilization ratio' => array('RATIOU', 
 134          'select round((sga.bytes/case when p.value=0 then sga.bytes else to_number(p.value) end)*100,2)
 135          from v$sgastat sga, v$parameter p
 136          where sga.name = \'free memory\' and sga.pool = \'shared pool\'
 137          and p.name = \'shared_pool_size\'',
 138          'Percentage of shared pool actually used - too low is bad, too high is worse'),
 139          
 140          'large pool utilization ratio' => array('RATIOU',
 141              "select round((1-bytes/sgasize)*100, 2)
 142              from (select sum(bytes) sgasize from sys.v_\$sgastat) s, sys.v_\$sgastat f
 143              where name = 'free memory' and pool = 'large pool'",
 144          'Percentage of large_pool actually in use - too low is bad, too high is worse'),
 145          'sort buffer size' => array('CACHE',
 146              "select value from v\$parameter where name='sort_area_size'",
 147              'max in-mem sort_area_size (per query), uses memory in pga' ),
 148  
 149          'pga usage at peak' => array('RATIOU',
 150          '=PGA','Mb utilization at peak transactions (requires Oracle 9i+)'),
 151      'Transactions',
 152          'rollback segments' => array('ROLLBACK',
 153              "select count(*) from sys.v_\$rollstat",
 154              ''),
 155      
 156          'peak transactions' => array('ROLLBACK',
 157              "select max_utilization  tx_hwm
 158              from sys.v_\$resource_limit
 159              where resource_name = 'transactions'",
 160              'Taken from high-water-mark'),
 161          'max transactions' => array('ROLLBACK',
 162              "select value from v\$parameter where name = 'transactions'",
 163              'max transactions / rollback segments < 3.5 (or transactions_per_rollback_segment)'),
 164      'Parameters',    
 165          'cursor sharing' => array('CURSOR',
 166              "select value from v\$parameter where name = 'cursor_sharing'",
 167              'Cursor reuse strategy. Recommended is FORCE (8i+) or SIMILAR (9i+). See <a href=http://www.praetoriate.com/oracle_tips_cursor_sharing.htm>cursor_sharing</a>.'),
 168          /*
 169          'cursor reuse' => array('CURSOR',
 170              "select count(*) from (select sql_text_wo_constants, count(*)
 171    from t1
 172   group by sql_text_wo_constants
 173  having count(*) > 100)",'These are sql statements that should be using bind variables'),*/
 174          'index cache cost' => array('COST',
 175              "select value from v\$parameter where name = 'optimizer_index_caching'",
 176              '=WarnIndexCost'),
 177          'random page cost' => array('COST',
 178              "select value from v\$parameter where name = 'optimizer_index_cost_adj'",
 179              '=WarnPageCost'),
 180          
 181      'Backup',
 182          'Achivelog Mode' => array('BACKUP', 'select log_mode from v$database', 'To turn on archivelog:<br>
 183      <pre>
 184          SQLPLUS> connect sys as sysdba;
 185          SQLPLUS> shutdown immediate;
 186  
 187          SQLPLUS> startup mount exclusive;
 188          SQLPLUS> alter database archivelog;
 189          SQLPLUS> archive log start;
 190          SQLPLUS> alter database open;
 191  </pre>'),
 192      
 193          'DBID' => array('BACKUP','select dbid from v$database','Primary key of database, used for recovery with an RMAN Recovery Catalog'),
 194          'Archive Log Dest' => array('BACKUP', "SELECT NVL(v1.value,v2.value) 
 195  FROM v\$parameter v1, v\$parameter v2 WHERE v1.name='log_archive_dest' AND v2.name='log_archive_dest_10'", ''),
 196      
 197          'Flashback Area' => array('BACKUP', "select nvl(value,'Flashback Area not used') from v\$parameter where name=lower('DB_RECOVERY_FILE_DEST')", 'Flashback area is a folder where all backup data and logs can be stored and managed by Oracle. If Error: message displayed, then it is not in use.'),
 198      
 199          'Flashback Usage' => array('BACKUP', "select nvl('-','Flashback Area not used') from v\$parameter where name=lower('DB_RECOVERY_FILE_DEST')", '=FlashUsage', 'Flashback area usage.'),
 200          
 201          'Control File Keep Time' => array('BACKUP', "select value from v\$parameter where name='control_file_record_keep_time'",'No of days to keep RMAN info in control file. I recommend it be set to x2 or x3 times the frequency of your full backup.'),
 202          'Recent RMAN Jobs' => array('BACKUP', "select '-' from dual", "=RMAN"),
 203          
 204          //        'Control File Keep Time' => array('BACKUP', "select value from v\$parameter where name='control_file_record_keep_time'",'No of days to keep RMAN info in control file. I recommend it be set to x2 or x3 times the frequency of your full backup.'),
 205  
 206          false
 207          
 208      );
 209      
 210      
 211  	function perf_oci8(&$conn)
 212      {
 213          $savelog = $conn->LogSQL(false);    
 214          $this->version = $conn->ServerInfo();
 215          $conn->LogSQL($savelog);    
 216          $this->conn = $conn;
 217      }
 218      
 219  	function RMAN()
 220      {
 221          $rs = $this->conn->Execute("select * from (select start_time, end_time, operation, status, mbytes_processed, output_device_type  
 222              from V\$RMAN_STATUS order by start_time desc) where rownum <=10");
 223          
 224          $ret = rs2html($rs,false,false,false,false);        
 225          return "&nbsp;<p>".$ret."&nbsp;</p>";
 226          
 227      }
 228  	function DynMemoryUsage()
 229      {
 230          if (@$this->version['version'] >= 11) {
 231              $rs = $this->conn->Execute("select component, current_size/1024./1024 as \"CurrSize (M)\" from  V\$MEMORY_DYNAMIC_COMPONENTS");
 232  
 233          } else
 234              $rs = $this->conn->Execute("select name, round(bytes/1024./1024,2) as \"CurrSize (M)\" from  V\$sgainfo");
 235  
 236              
 237          $ret = rs2html($rs,false,false,false,false);        
 238          return "&nbsp;<p>".$ret."&nbsp;</p>";
 239      }
 240      
 241  	function FlashUsage()
 242      {
 243          $rs = $this->conn->Execute("select * from  V\$FLASH_RECOVERY_AREA_USAGE");
 244          $ret = rs2html($rs,false,false,false,false);        
 245          return "&nbsp;<p>".$ret."&nbsp;</p>";
 246      }
 247      
 248  	function WarnPageCost($val)
 249      {
 250          if ($val == 100) $s = '<font color=red><b>Too High</b>. </font>';
 251          else $s = '';
 252          
 253          return $s.'Recommended is 20-50 for TP, and 50 for data warehouses. Default is 100. See <a href=http://www.dba-oracle.com/oracle_tips_cost_adj.htm>optimizer_index_cost_adj</a>. ';
 254      }
 255      
 256  	function WarnIndexCost($val)
 257      {
 258          if ($val == 0) $s = '<font color=red><b>Too Low</b>. </font>';
 259          else $s = '';
 260          
 261          return $s.'Percentage of indexed data blocks expected in the cache.
 262              Recommended is 20 (fast disk array) to 30 (slower hard disks). Default is 0.
 263               See <a href=http://www.dba-oracle.com/oracle_tips_cbo_part1.htm>optimizer_index_caching</a>.';
 264          }
 265      
 266  	function PGA()
 267      {
 268          if ($this->version['version'] < 9) return 'Oracle 9i or later required';
 269          
 270          $rs = $this->conn->Execute("select a.mb,a.targ as pga_size_pct,a.pct from 
 271         (select round(pga_target_for_estimate/1024.0/1024.0,0) MB,
 272                pga_target_factor targ,estd_pga_cache_hit_percentage pct,rownum as r 
 273                from v\$pga_target_advice) a left join
 274         (select round(pga_target_for_estimate/1024.0/1024.0,0) MB,
 275                pga_target_factor targ,estd_pga_cache_hit_percentage pct,rownum as r 
 276                from v\$pga_target_advice) b on 
 277        a.r = b.r+1 where 
 278            b.pct < 100");
 279          if (!$rs) return "Only in 9i or later";
 280          $rs->Close();
 281          if ($rs->EOF) return "PGA could be too big";
 282          
 283          return reset($rs->fields);
 284      }
 285      
 286  	function Explain($sql,$partial=false) 
 287      {
 288          $savelog = $this->conn->LogSQL(false);
 289          $rs = $this->conn->SelectLimit("select ID FROM PLAN_TABLE");
 290          if (!$rs) {
 291              echo "<p><b>Missing PLAN_TABLE</b></p>
 292  <pre>
 293  CREATE TABLE PLAN_TABLE (
 294    STATEMENT_ID                    VARCHAR2(30),
 295    TIMESTAMP                       DATE,
 296    REMARKS                         VARCHAR2(80),
 297    OPERATION                       VARCHAR2(30),
 298    OPTIONS                         VARCHAR2(30),
 299    OBJECT_NODE                     VARCHAR2(128),
 300    OBJECT_OWNER                    VARCHAR2(30),
 301    OBJECT_NAME                     VARCHAR2(30),
 302    OBJECT_INSTANCE                 NUMBER(38),
 303    OBJECT_TYPE                     VARCHAR2(30),
 304    OPTIMIZER                       VARCHAR2(255),
 305    SEARCH_COLUMNS                  NUMBER,
 306    ID                              NUMBER(38),
 307    PARENT_ID                       NUMBER(38),
 308    POSITION                        NUMBER(38),
 309    COST                            NUMBER(38),
 310    CARDINALITY                     NUMBER(38),
 311    BYTES                           NUMBER(38),
 312    OTHER_TAG                       VARCHAR2(255),
 313    PARTITION_START                 VARCHAR2(255),
 314    PARTITION_STOP                  VARCHAR2(255),
 315    PARTITION_ID                    NUMBER(38),
 316    OTHER                           LONG,
 317    DISTRIBUTION                    VARCHAR2(30)
 318  );
 319  </pre>";
 320              return false;
 321          }
 322          
 323          $rs->Close();
 324      //    $this->conn->debug=1;
 325      
 326          if ($partial) {
 327              $sqlq = $this->conn->qstr($sql.'%');
 328              $arr = $this->conn->GetArray("select distinct sql1 from adodb_logsql where sql1 like $sqlq");
 329              if ($arr) {
 330                  foreach($arr as $row) {
 331                      $sql = reset($row);
 332                      if (crc32($sql) == $partial) break;
 333                  }
 334              }
 335          }
 336          
 337          $s = "<p><b>Explain</b>: ".htmlspecialchars($sql)."</p>";    
 338          
 339          $this->conn->BeginTrans();
 340          $id = "ADODB ".microtime();
 341  
 342          $rs = $this->conn->Execute("EXPLAIN PLAN SET STATEMENT_ID='$id' FOR $sql");
 343          $m = $this->conn->ErrorMsg();
 344          if ($m) {
 345              $this->conn->RollbackTrans();
 346              $this->conn->LogSQL($savelog);
 347              $s .= "<p>$m</p>";
 348              return $s;
 349          }
 350          $rs = $this->conn->Execute("
 351          select 
 352    '<pre>'||lpad('--', (level-1)*2,'-') || trim(operation) || ' ' || trim(options)||'</pre>'  as Operation, 
 353    object_name,COST,CARDINALITY,bytes
 354          FROM plan_table 
 355  START WITH id = 0  and STATEMENT_ID='$id'  
 356  CONNECT BY prior id=parent_id and statement_id='$id'");
 357          
 358          $s .= rs2html($rs,false,false,false,false);
 359          $this->conn->RollbackTrans();
 360          $this->conn->LogSQL($savelog);
 361          $s .= $this->Tracer($sql,$partial);
 362          return $s;
 363      }
 364      
 365      
 366  	function CheckMemory()
 367      {
 368          if ($this->version['version'] < 9) return 'Oracle 9i or later required';
 369          
 370           $rs = $this->conn->Execute("
 371  select  b.size_for_estimate as cache_mb_estimate, 
 372      case when b.size_factor=1 then 
 373             '&lt;&lt;= Current'
 374       when a.estd_physical_read_factor-b.estd_physical_read_factor > 0.001 and b.estd_physical_read_factor<1 then
 375          '- BETTER than current by ' || round((1-b.estd_physical_read_factor)/b.estd_physical_read_factor*100,2) || '%'
 376      else ' ' end as RATING, 
 377     b.estd_physical_read_factor \"Phys. Reads Factor\",
 378     round((a.estd_physical_read_factor-b.estd_physical_read_factor)/b.estd_physical_read_factor*100,2) as \"% Improve\"
 379     from (select size_for_estimate,size_factor,estd_physical_read_factor,rownum  r from v\$db_cache_advice order by 1) a , 
 380     (select size_for_estimate,size_factor,estd_physical_read_factor,rownum r from v\$db_cache_advice order by 1) b where a.r = b.r-1
 381    ");
 382          if (!$rs) return false;
 383          
 384          /*
 385          The v$db_cache_advice utility show the marginal changes in physical data block reads for different sizes of db_cache_size
 386          */
 387          $s = "<h3>Data Cache Estimate</h3>";
 388          if ($rs->EOF) {
 389              $s .= "<p>Cache that is 50% of current size is still too big</p>";
 390          } else {
 391              $s .= "Ideal size of Data Cache is when %Improve gets close to zero.";
 392              $s .= rs2html($rs,false,false,false,false);
 393          }
 394          return $s;
 395      }
 396      
 397      /*
 398          Generate html for suspicious/expensive sql
 399      */
 400  	function tohtml(&$rs,$type)
 401      {
 402          $o1 = $rs->FetchField(0);
 403          $o2 = $rs->FetchField(1);
 404          $o3 = $rs->FetchField(2);
 405          if ($rs->EOF) return '<p>None found</p>';
 406          $check = '';
 407          $sql = '';
 408          $s = "\n\n<table border=1 bgcolor=white><tr><td><b>".$o1->name.'</b></td><td><b>'.$o2->name.'</b></td><td><b>'.$o3->name.'</b></td></tr>';
 409          while (!$rs->EOF) {
 410              if ($check != $rs->fields[0].'::'.$rs->fields[1]) {
 411                  if ($check) {
 412                      $carr = explode('::',$check);
 413                      $prefix = "<a href=\"?$type=1&sql=".rawurlencode($sql).'&x#explain">';
 414                      $suffix = '</a>';
 415                      if (strlen($prefix)>2000) {
 416                          $prefix = '';
 417                          $suffix = '';
 418                      }
 419                      
 420                      $s .=  "\n<tr><td align=right>".$carr[0].'</td><td align=right>'.$carr[1].'</td><td>'.$prefix.$sql.$suffix.'</td></tr>';
 421                  }
 422                  $sql = $rs->fields[2];
 423                  $check = $rs->fields[0].'::'.$rs->fields[1];            
 424              } else
 425                  $sql .= $rs->fields[2];
 426              if (substr($sql,strlen($sql)-1) == "\0") $sql = substr($sql,0,strlen($sql)-1);
 427              $rs->MoveNext();
 428          }
 429          $rs->Close();
 430          
 431          $carr = explode('::',$check);
 432          $prefix = "<a target=".rand()." href=\"?&hidem=1&$type=1&sql=".rawurlencode($sql).'&x#explain">';
 433          $suffix = '</a>';
 434          if (strlen($prefix)>2000) {
 435              $prefix = '';
 436              $suffix = '';
 437          }
 438          $s .=  "\n<tr><td align=right>".$carr[0].'</td><td align=right>'.$carr[1].'</td><td>'.$prefix.$sql.$suffix.'</td></tr>';
 439                      
 440          return $s."</table>\n\n";
 441      }
 442      
 443      // code thanks to Ixora. 
 444      // http://www.ixora.com.au/scripts/query_opt.htm
 445      // requires oracle 8.1.7 or later
 446  	function SuspiciousSQL($numsql=10)
 447      {
 448          $sql = "
 449  select
 450    substr(to_char(s.pct, '99.00'), 2) || '%'  load,
 451    s.executions  executes,
 452    p.sql_text
 453  from
 454    ( 
 455      select
 456        address,
 457        buffer_gets,
 458        executions,
 459        pct,
 460        rank() over (order by buffer_gets desc)  ranking
 461      from
 462        ( 
 463      select
 464        address,
 465        buffer_gets,
 466        executions,
 467        100 * ratio_to_report(buffer_gets) over ()  pct
 468      from
 469        sys.v_\$sql
 470      where
 471        command_type != 47 and module != 'T.O.A.D.'
 472        )
 473      where
 474        buffer_gets > 50 * executions
 475    )  s,
 476    sys.v_\$sqltext  p
 477  where
 478    s.ranking <= $numsql and
 479    p.address = s.address
 480  order by
 481    1 desc, s.address, p.piece";
 482  
 483            global $ADODB_CACHE_MODE;
 484            if (isset($_GET['expsixora']) && isset($_GET['sql'])) {
 485                  $partial = empty($_GET['part']);
 486                  echo "<a name=explain></a>".$this->Explain($_GET['sql'],$partial)."\n";
 487          }
 488  
 489          if (isset($_GET['sql'])) return $this->_SuspiciousSQL($numsql);
 490          
 491          $s = '';
 492          $timer = time();
 493          $s .= $this->_SuspiciousSQL($numsql);
 494          $timer = time() - $timer;
 495          
 496          if ($timer > $this->noShowIxora) return $s;
 497          $s .= '<p>';
 498          
 499          $save = $ADODB_CACHE_MODE;
 500          $ADODB_CACHE_MODE = ADODB_FETCH_NUM;
 501          if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
 502          
 503          $savelog = $this->conn->LogSQL(false);
 504          $rs = $this->conn->SelectLimit($sql);
 505          $this->conn->LogSQL($savelog);
 506          
 507          if (isset($savem)) $this->conn->SetFetchMode($savem);
 508          $ADODB_CACHE_MODE = $save;
 509          if ($rs) {
 510              $s .= "\n<h3>Ixora Suspicious SQL</h3>";
 511              $s .= $this->tohtml($rs,'expsixora');
 512          }
 513          
 514          return $s;
 515      }
 516      
 517      // code thanks to Ixora. 
 518      // http://www.ixora.com.au/scripts/query_opt.htm
 519      // requires oracle 8.1.7 or later
 520  	function ExpensiveSQL($numsql = 10)
 521      {
 522          $sql = "
 523  select
 524    substr(to_char(s.pct, '99.00'), 2) || '%'  load,
 525    s.executions  executes,
 526    p.sql_text
 527  from
 528    ( 
 529      select
 530        address,
 531        disk_reads,
 532        executions,
 533        pct,
 534        rank() over (order by disk_reads desc)  ranking
 535      from
 536        (
 537      select
 538        address,
 539        disk_reads,
 540        executions,
 541        100 * ratio_to_report(disk_reads) over ()  pct
 542      from
 543        sys.v_\$sql
 544      where
 545        command_type != 47 and module != 'T.O.A.D.'
 546        )
 547      where
 548        disk_reads > 50 * executions
 549    )  s,
 550    sys.v_\$sqltext  p
 551  where
 552    s.ranking <= $numsql and
 553    p.address = s.address
 554  order by
 555    1 desc, s.address, p.piece
 556  ";
 557          global $ADODB_CACHE_MODE;
 558            if (isset($_GET['expeixora']) && isset($_GET['sql'])) {
 559              $partial = empty($_GET['part']);    
 560              echo "<a name=explain></a>".$this->Explain($_GET['sql'],$partial)."\n";
 561          }
 562          if (isset($_GET['sql'])) {
 563               $var = $this->_ExpensiveSQL($numsql);
 564               return $var;
 565          }
 566          
 567          $s = '';        
 568          $timer = time();
 569          $s .= $this->_ExpensiveSQL($numsql);
 570          $timer = time() - $timer;
 571          if ($timer > $this->noShowIxora) return $s;
 572          
 573          $s .= '<p>';
 574          $save = $ADODB_CACHE_MODE;
 575          $ADODB_CACHE_MODE = ADODB_FETCH_NUM;
 576          if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
 577          
 578          $savelog = $this->conn->LogSQL(false);
 579          $rs = $this->conn->Execute($sql);
 580          $this->conn->LogSQL($savelog);
 581          
 582          if (isset($savem)) $this->conn->SetFetchMode($savem);
 583          $ADODB_CACHE_MODE = $save;
 584          
 585          if ($rs) {
 586              $s .= "\n<h3>Ixora Expensive SQL</h3>";
 587              $s .= $this->tohtml($rs,'expeixora');
 588          }
 589      
 590          return $s;
 591      }
 592      
 593  	function clearsql() 
 594      {
 595          $perf_table = adodb_perf::table();
 596      // using the naive "delete from $perf_table where created<".$this->conn->sysTimeStamp will cause the table to lock, possibly
 597      // for a long time
 598          $sql = 
 599  "DECLARE cnt pls_integer;
 600  BEGIN
 601      cnt := 0;
 602      FOR rec IN (SELECT ROWID AS rr FROM $perf_table WHERE created<SYSDATE) 
 603      LOOP
 604        cnt := cnt + 1;
 605        DELETE FROM $perf_table WHERE ROWID=rec.rr;
 606        IF cnt = 1000 THEN
 607            COMMIT;
 608          cnt := 0;
 609        END IF;
 610      END LOOP;
 611      commit;
 612  END;";
 613  
 614          $ok = $this->conn->Execute($sql);
 615      }
 616      
 617  }
 618  ?>


Generated: Thu Jul 28 15:48:31 2011 Cross-referenced by PHPXref 0.7