[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

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

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


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1