Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/adodb/perf/perf-oci8.inc.php
Go to the documentation of this file.
00001 <?php
00002 /* 
00003 V5.14 8 Sept 2011  (c) 2000-2011 John Lim (jlim#natsoft.com). All rights reserved.
00004   Released under both BSD license and Lesser GPL library license. 
00005   Whenever there is any discrepancy between the two licenses, 
00006   the BSD license will take precedence. See License.txt. 
00007   Set tabs to 4 for best viewing.
00008   
00009   Latest version is available at http://adodb.sourceforge.net
00010   
00011   Library for basic performance monitoring and tuning 
00012   
00013 */
00014 
00015 // security - hide paths
00016 if (!defined('ADODB_DIR')) die();
00017 
00018 
00019 class perf_oci8 extends ADODB_perf{
00020 
00021         var $noShowIxora = 15; // if the sql for suspicious sql is taking too long, then disable ixora
00022         
00023         var $tablesSQL = "select segment_name as \"tablename\", sum(bytes)/1024 as \"size_in_k\",tablespace_name as \"tablespace\",count(*) \"extents\" from sys.user_extents 
00024            group by segment_name,tablespace_name";
00025          
00026         var $version;
00027         
00028         var $createTableSQL = "CREATE TABLE adodb_logsql (
00029                   created date NOT NULL,
00030                   sql0 varchar(250) NOT NULL,
00031                   sql1 varchar(4000) NOT NULL,
00032                   params varchar(4000),
00033                   tracer varchar(4000),
00034                   timer decimal(16,6) NOT NULL
00035                 )";
00036         
00037         var $settings = array(
00038         'Ratios',
00039                 'data cache hit ratio' => array('RATIOH',
00040                         "select round((1-(phy.value / (cur.value + con.value)))*100,2) 
00041                         from v\$sysstat cur, v\$sysstat con, v\$sysstat phy
00042                         where cur.name = 'db block gets' and
00043                               con.name = 'consistent gets' and
00044                               phy.name = 'physical reads'",
00045                         '=WarnCacheRatio'),
00046                 
00047                 'sql cache hit ratio' => array( 'RATIOH',
00048                         'select round(100*(sum(pins)-sum(reloads))/sum(pins),2)  from v$librarycache',
00049                         'increase <i>shared_pool_size</i> if too ratio low'),
00050                         
00051                 'datadict cache hit ratio' => array('RATIOH',
00052                 "select      
00053            round((1 - (sum(getmisses) / (sum(gets) +          
00054                  sum(getmisses))))*100,2)
00055                 from  v\$rowcache",
00056                 'increase <i>shared_pool_size</i> if too ratio low'),
00057                 
00058                 'memory sort ratio' => array('RATIOH',
00059                 "SELECT ROUND((100 * b.VALUE) /DECODE ((a.VALUE + b.VALUE), 
00060        0,1,(a.VALUE + b.VALUE)),2)
00061 FROM   v\$sysstat a, 
00062        v\$sysstat b
00063 WHERE  a.name = 'sorts (disk)'
00064 AND    b.name = 'sorts (memory)'",
00065         "% of memory sorts compared to disk sorts - should be over 95%"),
00066 
00067         'IO',
00068                 'data reads' => array('IO',
00069                 "select value from v\$sysstat where name='physical reads'"),
00070         
00071         'data writes' => array('IO',
00072                 "select value from v\$sysstat where name='physical writes'"),
00073         
00074         'Data Cache',
00075         
00076                 'data cache buffers' => array( 'DATAC',
00077                 "select a.value/b.value  from v\$parameter a, v\$parameter b 
00078                         where a.name = 'db_cache_size' and b.name= 'db_block_size'",
00079                         'Number of cache buffers. Tune <i>db_cache_size</i> if the <i>data cache hit ratio</i> is too low.'),
00080                 'data cache blocksize' => array('DATAC',
00081                         "select value from v\$parameter where name='db_block_size'",
00082                         '' ),                   
00083         
00084         'Memory Pools',
00085                 'Mem Max Target (11g+)' => array( 'DATAC',
00086                 "select value from v\$parameter where name = 'memory_max_target'",
00087                         'The memory_max_size is the maximum value to which memory_target can be set.' ),
00088         'Memory target (11g+)' => array( 'DATAC',
00089                 "select value from v\$parameter where name = 'memory_target'",
00090                         'If memory_target is defined then SGA and PGA targets are consolidated into one memory_target.' ),
00091                 'SGA Max Size' => array( 'DATAC',
00092                 "select nvl(value,0)/1024.0/1024 || 'M' from v\$parameter where name = 'sga_max_size'",
00093                         'The sga_max_size is the maximum value to which sga_target can be set.' ),
00094         'SGA target' => array( 'DATAC',
00095                 "select nvl(value,0)/1024.0/1024 || 'M'  from v\$parameter where name = 'sga_target'",
00096                         '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.' ),
00097         'PGA aggr target' => array( 'DATAC',
00098                 "select nvl(value,0)/1024.0/1024 || 'M' from v\$parameter where name = 'pga_aggregate_target'",
00099                         '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.' ),
00100         'data cache size' => array('DATAC',
00101                         "select value from v\$parameter where name = 'db_cache_size'",
00102                         'db_cache_size' ),
00103                 'shared pool size' => array('DATAC',
00104                         "select value from v\$parameter where name = 'shared_pool_size'",
00105                         'shared_pool_size, which holds shared sql, stored procedures, dict cache and similar shared structs' ),
00106                 'java pool size' => array('DATAJ',
00107                         "select value from v\$parameter where name = 'java_pool_size'",
00108                         'java_pool_size' ),
00109                 'large pool buffer size' => array('CACHE',
00110                         "select value from v\$parameter where name='large_pool_size'",
00111                         '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) ' ),
00112 
00113                 'dynamic memory usage' => array('CACHE', "select '-' from dual", '=DynMemoryUsage'),
00114                 
00115                 'Connections',
00116                 'current connections' => array('SESS',
00117                         'select count(*) from sys.v_$session where username is not null',
00118                         ''),
00119                 'max connections' => array( 'SESS',
00120                         "select value from v\$parameter where name='sessions'",
00121                         ''),
00122 
00123         'Memory Utilization',           
00124                 'data cache utilization ratio' => array('RATIOU',
00125                         "select round((1-bytes/sgasize)*100, 2)
00126                         from (select sum(bytes) sgasize from sys.v_\$sgastat) s, sys.v_\$sgastat f
00127                         where name = 'free memory' and pool = 'shared pool'",
00128                 'Percentage of data cache actually in use - should be over 85%'),
00129                 
00130                 'shared pool utilization ratio' => array('RATIOU', 
00131                 'select round((sga.bytes/case when p.value=0 then sga.bytes else to_number(p.value) end)*100,2)
00132                 from v$sgastat sga, v$parameter p
00133                 where sga.name = \'free memory\' and sga.pool = \'shared pool\'
00134                 and p.name = \'shared_pool_size\'',
00135                 'Percentage of shared pool actually used - too low is bad, too high is worse'),
00136                 
00137                 'large pool utilization ratio' => array('RATIOU',
00138                         "select round((1-bytes/sgasize)*100, 2)
00139                         from (select sum(bytes) sgasize from sys.v_\$sgastat) s, sys.v_\$sgastat f
00140                         where name = 'free memory' and pool = 'large pool'",
00141                 'Percentage of large_pool actually in use - too low is bad, too high is worse'),
00142                 'sort buffer size' => array('CACHE',
00143                         "select value from v\$parameter where name='sort_area_size'",
00144                         'max in-mem sort_area_size (per query), uses memory in pga' ),
00145 
00146                 /*'pga usage at peak' => array('RATIOU',
00147                 '=PGA','Mb utilization at peak transactions (requires Oracle 9i+)'),*/
00148         'Transactions',
00149                 'rollback segments' => array('ROLLBACK',
00150                         "select count(*) from sys.v_\$rollstat",
00151                         ''),
00152         
00153                 'peak transactions' => array('ROLLBACK',
00154                         "select max_utilization  tx_hwm
00155                 from sys.v_\$resource_limit
00156                 where resource_name = 'transactions'",
00157                         'Taken from high-water-mark'),
00158                 'max transactions' => array('ROLLBACK',
00159                         "select value from v\$parameter where name = 'transactions'",
00160                         'max transactions / rollback segments < 3.5 (or transactions_per_rollback_segment)'),
00161         'Parameters',   
00162                 'cursor sharing' => array('CURSOR',
00163                         "select value from v\$parameter where name = 'cursor_sharing'",
00164                         '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>.'),
00165                 /*
00166                 'cursor reuse' => array('CURSOR',
00167                         "select count(*) from (select sql_text_wo_constants, count(*)
00168   from t1
00169  group by sql_text_wo_constants
00170 having count(*) > 100)",'These are sql statements that should be using bind variables'),*/
00171                 'index cache cost' => array('COST',
00172                         "select value from v\$parameter where name = 'optimizer_index_caching'",
00173                         '=WarnIndexCost'),
00174                 'random page cost' => array('COST',
00175                         "select value from v\$parameter where name = 'optimizer_index_cost_adj'",
00176                         '=WarnPageCost'),
00177         'Waits',
00178                 'Recent wait events' => array('WAITS','select \'Top 5 events\' from dual','=TopRecentWaits'),
00179 //              'Historical wait SQL' => array('WAITS','select \'Last 2 days\' from dual','=TopHistoricalWaits'), -- requires AWR license
00180         'Backup',
00181                 'Achivelog Mode' => array('BACKUP', 'select log_mode from v$database', '=LogMode'),
00182         
00183                 'DBID' => array('BACKUP','select dbid from v$database','Primary key of database, used for recovery with an RMAN Recovery Catalog'),
00184                 'Archive Log Dest' => array('BACKUP', "SELECT NVL(v1.value,v2.value) 
00185 FROM v\$parameter v1, v\$parameter v2 WHERE v1.name='log_archive_dest' AND v2.name='log_archive_dest_10'", ''),
00186         
00187                 '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.'),
00188         
00189                 'Flashback Usage' => array('BACKUP', "select nvl('-','Flashback Area not used') from v\$parameter where name=lower('DB_RECOVERY_FILE_DEST')", '=FlashUsage', 'Flashback area usage.'),
00190                 
00191                 '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.'),
00192                 'Recent RMAN Jobs' => array('BACKUP', "select '-' from dual", "=RMAN"),
00193                 
00194                 //              '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.'),
00195 
00196                 false
00197                 
00198         );
00199         
00200         
00201         function perf_oci8(&$conn)
00202         {
00203         global $gSQLBlockRows;
00204         
00205                 $gSQLBlockRows = 1000;
00206                 $savelog = $conn->LogSQL(false);        
00207                 $this->version = $conn->ServerInfo();
00208                 $conn->LogSQL($savelog);        
00209                 $this->conn = $conn;
00210         }
00211         
00212         function LogMode()
00213         {
00214                 $mode = $this->conn->GetOne("select log_mode from v\$database");
00215                 
00216                 if ($mode == 'ARCHIVELOG') return 'To turn off archivelog:<br>
00217         <pre><font size=-2>
00218         SQLPLUS> connect sys as sysdba;
00219         SQLPLUS> shutdown immediate;
00220 
00221         SQLPLUS> startup mount exclusive;
00222         SQLPLUS> alter database noarchivelog;
00223         SQLPLUS> alter database open;
00224 </font></pre>';
00225                 
00226                 return 'To turn on archivelog:<br>
00227         <pre><font size=-2>
00228         SQLPLUS> connect sys as sysdba;
00229         SQLPLUS> shutdown immediate;
00230 
00231         SQLPLUS> startup mount exclusive;
00232         SQLPLUS> alter database archivelog;
00233         SQLPLUS> archive log start;
00234         SQLPLUS> alter database open;
00235 </font></pre>';
00236         }
00237         
00238         function TopRecentWaits()
00239         {
00240                 
00241                 $rs = $this->conn->Execute("select * from (   
00242                 select event, round(100*time_waited/(select sum(time_waited) from v\$system_event where wait_class <> 'Idle'),1) \"% Wait\",
00243     total_waits,time_waited, average_wait,wait_class from v\$system_event where wait_class <> 'Idle' order by 2 desc
00244         ) where rownum <=5");
00245                 
00246                 $ret = rs2html($rs,false,false,false,false);            
00247                 return "&nbsp;<p>".$ret."&nbsp;</p>";
00248                 
00249         }
00250         
00251         function TopHistoricalWaits()
00252         {
00253                 $days = 2;
00254                 
00255                 $rs = $this->conn->Execute("select * from (   SELECT
00256          b.wait_class,B.NAME,
00257         round(sum(wait_time+TIME_WAITED)/1000000) waitsecs,
00258         parsing_schema_name,
00259         C.SQL_TEXT, a.sql_id
00260 FROM    V\$ACTIVE_SESSION_HISTORY A
00261         join V\$EVENT_NAME B  on  A.EVENT# = B.EVENT#
00262        join V\$SQLAREA C  on  A.SQL_ID = C.SQL_ID
00263 WHERE   A.SAMPLE_TIME BETWEEN sysdate-$days and sysdate
00264        and parsing_schema_name not in ('SYS','SYSMAN','DBSNMP','SYSTEM')
00265 GROUP BY b.wait_class,parsing_schema_name,C.SQL_TEXT, B.NAME,A.sql_id
00266 order by 3 desc) where rownum <=10");
00267                 
00268                 $ret = rs2html($rs,false,false,false,false);            
00269                 return "&nbsp;<p>".$ret."&nbsp;</p>";
00270                 
00271         }
00272         
00273         function RMAN()
00274         {
00275                 $rs = $this->conn->Execute("select * from (select start_time, end_time, operation, status, mbytes_processed, output_device_type  
00276                         from V\$RMAN_STATUS order by start_time desc) where rownum <=10");
00277                 
00278                 $ret = rs2html($rs,false,false,false,false);            
00279                 return "&nbsp;<p>".$ret."&nbsp;</p>";
00280                 
00281         }
00282         function DynMemoryUsage()
00283         {
00284                 if (@$this->version['version'] >= 11) {
00285                         $rs = $this->conn->Execute("select component, current_size/1024./1024 as \"CurrSize (M)\" from  V\$MEMORY_DYNAMIC_COMPONENTS");
00286 
00287                 } else
00288                         $rs = $this->conn->Execute("select name, round(bytes/1024./1024,2) as \"CurrSize (M)\" from  V\$sgainfo");
00289 
00290                         
00291                 $ret = rs2html($rs,false,false,false,false);            
00292                 return "&nbsp;<p>".$ret."&nbsp;</p>";
00293         }
00294         
00295         function FlashUsage()
00296         {
00297         $rs = $this->conn->Execute("select * from  V\$FLASH_RECOVERY_AREA_USAGE");
00298                 $ret = rs2html($rs,false,false,false,false);            
00299                 return "&nbsp;<p>".$ret."&nbsp;</p>";
00300         }
00301         
00302         function WarnPageCost($val)
00303         {
00304                 if ($val == 100 && $this->version['version'] < 10) $s = '<font color=red><b>Too High</b>. </font>';
00305                 else $s = '';
00306                 
00307                 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>. ';
00308         }
00309         
00310         function WarnIndexCost($val)
00311         {
00312                 if ($val == 0 && $this->version['version'] < 10) $s = '<font color=red><b>Too Low</b>. </font>';
00313                 else $s = '';
00314                 
00315                 return $s.'Percentage of indexed data blocks expected in the cache.
00316                         Recommended is 20 (fast disk array) to 30 (slower hard disks). Default is 0.
00317                          See <a href=http://www.dba-oracle.com/oracle_tips_cbo_part1.htm>optimizer_index_caching</a>.';
00318                 }
00319         
00320         function PGA()
00321         {       
00322                 
00323                 //if ($this->version['version'] < 9) return 'Oracle 9i or later required';
00324         }
00325         function PGA_Advice()
00326         {
00327                 $t = "<h3>PGA Advice Estimate</h3>";
00328                 if ($this->version['version'] < 9) return $t.'Oracle 9i or later required';
00329                 
00330                 $rs = $this->conn->Execute('select a.MB,
00331                         case when a.targ = 1 then \'<<= Current \' 
00332                         when a.targ < 1  or a.pct <= b.pct then null 
00333                         else 
00334                         \'- BETTER than Current by \'||round(a.pct/b.pct*100-100,2)||\'%\' end as "Percent Improved",
00335         a.targ as  "PGA Size Factor",a.pct "% Perf"
00336         from 
00337        (select round(pga_target_for_estimate/1024.0/1024.0,0) MB,
00338               pga_target_factor targ,estd_pga_cache_hit_percentage pct,rownum as r 
00339               from v$pga_target_advice) a left join
00340        (select round(pga_target_for_estimate/1024.0/1024.0,0) MB,
00341               pga_target_factor targ,estd_pga_cache_hit_percentage pct,rownum as r 
00342               from v$pga_target_advice) b on 
00343       a.r = b.r+1 where 
00344           b.pct < 100');
00345                 if (!$rs) return $t."Only in 9i or later";
00346         //      $rs->Close();
00347                 if ($rs->EOF) return $t."PGA could be too big";
00348                 
00349                 return $t.rs2html($rs,false,false,true,false);
00350         }
00351         
00352         function Explain($sql,$partial=false) 
00353         {
00354                 $savelog = $this->conn->LogSQL(false);
00355                 $rs = $this->conn->SelectLimit("select ID FROM PLAN_TABLE");
00356                 if (!$rs) {
00357                         echo "<p><b>Missing PLAN_TABLE</b></p>
00358 <pre>
00359 CREATE TABLE PLAN_TABLE (
00360   STATEMENT_ID                    VARCHAR2(30),
00361   TIMESTAMP                       DATE,
00362   REMARKS                         VARCHAR2(80),
00363   OPERATION                       VARCHAR2(30),
00364   OPTIONS                         VARCHAR2(30),
00365   OBJECT_NODE                     VARCHAR2(128),
00366   OBJECT_OWNER                    VARCHAR2(30),
00367   OBJECT_NAME                     VARCHAR2(30),
00368   OBJECT_INSTANCE                 NUMBER(38),
00369   OBJECT_TYPE                     VARCHAR2(30),
00370   OPTIMIZER                       VARCHAR2(255),
00371   SEARCH_COLUMNS                  NUMBER,
00372   ID                              NUMBER(38),
00373   PARENT_ID                       NUMBER(38),
00374   POSITION                        NUMBER(38),
00375   COST                            NUMBER(38),
00376   CARDINALITY                     NUMBER(38),
00377   BYTES                           NUMBER(38),
00378   OTHER_TAG                       VARCHAR2(255),
00379   PARTITION_START                 VARCHAR2(255),
00380   PARTITION_STOP                  VARCHAR2(255),
00381   PARTITION_ID                    NUMBER(38),
00382   OTHER                           LONG,
00383   DISTRIBUTION                    VARCHAR2(30)
00384 );
00385 </pre>";
00386                         return false;
00387                 }
00388                 
00389                 $rs->Close();
00390         //      $this->conn->debug=1;
00391         
00392                 if ($partial) {
00393                         $sqlq = $this->conn->qstr($sql.'%');
00394                         $arr = $this->conn->GetArray("select distinct sql1 from adodb_logsql where sql1 like $sqlq");
00395                         if ($arr) {
00396                                 foreach($arr as $row) {
00397                                         $sql = reset($row);
00398                                         if (crc32($sql) == $partial) break;
00399                                 }
00400                         }
00401                 }
00402                 
00403                 $s = "<p><b>Explain</b>: ".htmlspecialchars($sql)."</p>";       
00404                 
00405                 $this->conn->BeginTrans();
00406                 $id = "ADODB ".microtime();
00407 
00408                 $rs = $this->conn->Execute("EXPLAIN PLAN SET STATEMENT_ID='$id' FOR $sql");
00409                 $m = $this->conn->ErrorMsg();
00410                 if ($m) {
00411                         $this->conn->RollbackTrans();
00412                         $this->conn->LogSQL($savelog);
00413                         $s .= "<p>$m</p>";
00414                         return $s;
00415                 }
00416                 $rs = $this->conn->Execute("
00417                 select 
00418   '<pre>'||lpad('--', (level-1)*2,'-') || trim(operation) || ' ' || trim(options)||'</pre>'  as Operation, 
00419   object_name,COST,CARDINALITY,bytes
00420                 FROM plan_table 
00421 START WITH id = 0  and STATEMENT_ID='$id'  
00422 CONNECT BY prior id=parent_id and statement_id='$id'");
00423                 
00424                 $s .= rs2html($rs,false,false,false,false);
00425                 $this->conn->RollbackTrans();
00426                 $this->conn->LogSQL($savelog);
00427                 $s .= $this->Tracer($sql,$partial);
00428                 return $s;
00429         }
00430         
00431         
00432         function CheckMemory()
00433         {
00434                 if ($this->version['version'] < 9) return 'Oracle 9i or later required';
00435                 
00436                  $rs = $this->conn->Execute("
00437 select  a.name Buffer_Pool, b.size_for_estimate as cache_mb_estimate, 
00438         case when b.size_factor=1 then 
00439                 '&lt;&lt;= Current'
00440          when a.estd_physical_read_factor-b.estd_physical_read_factor > 0.001 and b.estd_physical_read_factor<1 then
00441                 '- BETTER than current by ' || round((1-b.estd_physical_read_factor)/b.estd_physical_read_factor*100,2) || '%'
00442         else ' ' end as RATING, 
00443    b.estd_physical_read_factor \"Phys. Reads Factor\",
00444    round((a.estd_physical_read_factor-b.estd_physical_read_factor)/b.estd_physical_read_factor*100,2) as \"% Improve\"
00445    from (select size_for_estimate,size_factor,estd_physical_read_factor,rownum  r,name from v\$db_cache_advice order by name,1) a , 
00446    (select size_for_estimate,size_factor,estd_physical_read_factor,rownum r,name from v\$db_cache_advice order by name,1) b 
00447    where a.r = b.r-1 and a.name = b.name
00448   ");
00449                 if (!$rs) return false;
00450                 
00451                 /*
00452                 The v$db_cache_advice utility show the marginal changes in physical data block reads for different sizes of db_cache_size
00453                 */
00454                 $s = "<h3>Data Cache Advice Estimate</h3>";
00455                 if ($rs->EOF) {
00456                         $s .= "<p>Cache that is 50% of current size is still too big</p>";
00457                 } else {
00458                         $s .= "Ideal size of Data Cache is when %BETTER gets close to zero.";
00459                         $s .= rs2html($rs,false,false,false,false);
00460                 }
00461                 return $s.$this->PGA_Advice();
00462         }
00463         
00464         /*
00465                 Generate html for suspicious/expensive sql
00466         */
00467         function tohtml(&$rs,$type)
00468         {
00469                 $o1 = $rs->FetchField(0);
00470                 $o2 = $rs->FetchField(1);
00471                 $o3 = $rs->FetchField(2);
00472                 if ($rs->EOF) return '<p>None found</p>';
00473                 $check = '';
00474                 $sql = '';
00475                 $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>';
00476                 while (!$rs->EOF) {
00477                         if ($check != $rs->fields[0].'::'.$rs->fields[1]) {
00478                                 if ($check) {
00479                                         $carr = explode('::',$check);
00480                                         $prefix = "<a href=\"?$type=1&sql=".rawurlencode($sql).'&x#explain">';
00481                                         $suffix = '</a>';
00482                                         if (strlen($prefix)>2000) {
00483                                                 $prefix = '';
00484                                                 $suffix = '';
00485                                         }
00486                                         
00487                                         $s .=  "\n<tr><td align=right>".$carr[0].'</td><td align=right>'.$carr[1].'</td><td>'.$prefix.$sql.$suffix.'</td></tr>';
00488                                 }
00489                                 $sql = $rs->fields[2];
00490                                 $check = $rs->fields[0].'::'.$rs->fields[1];                    
00491                         } else
00492                                 $sql .= $rs->fields[2];
00493                         if (substr($sql,strlen($sql)-1) == "\0") $sql = substr($sql,0,strlen($sql)-1);
00494                         $rs->MoveNext();
00495                 }
00496                 $rs->Close();
00497                 
00498                 $carr = explode('::',$check);
00499                 $prefix = "<a target=".rand()." href=\"?&hidem=1&$type=1&sql=".rawurlencode($sql).'&x#explain">';
00500                 $suffix = '</a>';
00501                 if (strlen($prefix)>2000) {
00502                         $prefix = '';
00503                         $suffix = '';
00504                 }
00505                 $s .=  "\n<tr><td align=right>".$carr[0].'</td><td align=right>'.$carr[1].'</td><td>'.$prefix.$sql.$suffix.'</td></tr>';
00506                                         
00507                 return $s."</table>\n\n";
00508         }
00509         
00510         // code thanks to Ixora. 
00511         // http://www.ixora.com.au/scripts/query_opt.htm
00512         // requires oracle 8.1.7 or later
00513         function SuspiciousSQL($numsql=10)
00514         {
00515                 $sql = "
00516 select
00517   substr(to_char(s.pct, '99.00'), 2) || '%'  load,
00518   s.executions  executes,
00519   p.sql_text
00520 from
00521   ( 
00522     select
00523       address,
00524       buffer_gets,
00525       executions,
00526       pct,
00527       rank() over (order by buffer_gets desc)  ranking
00528     from
00529       ( 
00530         select
00531           address,
00532           buffer_gets,
00533           executions,
00534           100 * ratio_to_report(buffer_gets) over ()  pct
00535         from
00536           sys.v_\$sql
00537         where
00538           command_type != 47 and module != 'T.O.A.D.'
00539       )
00540     where
00541       buffer_gets > 50 * executions
00542   )  s,
00543   sys.v_\$sqltext  p
00544 where
00545   s.ranking <= $numsql and
00546   p.address = s.address
00547 order by
00548   1 desc, s.address, p.piece";
00549 
00550                 global $ADODB_CACHE_MODE;
00551                 if (isset($_GET['expsixora']) && isset($_GET['sql'])) {
00552                                 $partial = empty($_GET['part']);
00553                                 echo "<a name=explain></a>".$this->Explain($_GET['sql'],$partial)."\n";
00554                 }
00555 
00556                 if (isset($_GET['sql'])) return $this->_SuspiciousSQL($numsql);
00557                 
00558                 $s = '';
00559                 $timer = time();
00560                 $s .= $this->_SuspiciousSQL($numsql);
00561                 $timer = time() - $timer;
00562                 
00563                 if ($timer > $this->noShowIxora) return $s;
00564                 $s .= '<p>';
00565                 
00566                 $save = $ADODB_CACHE_MODE;
00567                 $ADODB_CACHE_MODE = ADODB_FETCH_NUM;
00568                 if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
00569                 
00570                 $savelog = $this->conn->LogSQL(false);
00571                 $rs = $this->conn->SelectLimit($sql);
00572                 $this->conn->LogSQL($savelog);
00573                 
00574                 if (isset($savem)) $this->conn->SetFetchMode($savem);
00575                 $ADODB_CACHE_MODE = $save;
00576                 if ($rs) {
00577                         $s .= "\n<h3>Ixora Suspicious SQL</h3>";
00578                         $s .= $this->tohtml($rs,'expsixora');
00579                 }
00580                 
00581                 return $s;
00582         }
00583         
00584         // code thanks to Ixora. 
00585         // http://www.ixora.com.au/scripts/query_opt.htm
00586         // requires oracle 8.1.7 or later
00587         function ExpensiveSQL($numsql = 10)
00588         {
00589                 $sql = "
00590 select
00591   substr(to_char(s.pct, '99.00'), 2) || '%'  load,
00592   s.executions  executes,
00593   p.sql_text
00594 from
00595   ( 
00596     select
00597       address,
00598       disk_reads,
00599       executions,
00600       pct,
00601       rank() over (order by disk_reads desc)  ranking
00602     from
00603       (
00604         select
00605           address,
00606           disk_reads,
00607           executions,
00608           100 * ratio_to_report(disk_reads) over ()  pct
00609         from
00610           sys.v_\$sql
00611         where
00612           command_type != 47 and module != 'T.O.A.D.'
00613       )
00614     where
00615       disk_reads > 50 * executions
00616   )  s,
00617   sys.v_\$sqltext  p
00618 where
00619   s.ranking <= $numsql and
00620   p.address = s.address
00621 order by
00622   1 desc, s.address, p.piece
00623 ";
00624                 global $ADODB_CACHE_MODE;
00625                 if (isset($_GET['expeixora']) && isset($_GET['sql'])) {
00626                         $partial = empty($_GET['part']);        
00627                         echo "<a name=explain></a>".$this->Explain($_GET['sql'],$partial)."\n";
00628                 }
00629                 if (isset($_GET['sql'])) {
00630                          $var = $this->_ExpensiveSQL($numsql);
00631                          return $var;
00632                 }
00633                 
00634                 $s = '';                
00635                 $timer = time();
00636                 $s .= $this->_ExpensiveSQL($numsql);
00637                 $timer = time() - $timer;
00638                 if ($timer > $this->noShowIxora) return $s;
00639                 
00640                 $s .= '<p>';
00641                 $save = $ADODB_CACHE_MODE;
00642                 $ADODB_CACHE_MODE = ADODB_FETCH_NUM;
00643                 if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
00644                 
00645                 $savelog = $this->conn->LogSQL(false);
00646                 $rs = $this->conn->Execute($sql);
00647                 $this->conn->LogSQL($savelog);
00648                 
00649                 if (isset($savem)) $this->conn->SetFetchMode($savem);
00650                 $ADODB_CACHE_MODE = $save;
00651                 
00652                 if ($rs) {
00653                         $s .= "\n<h3>Ixora Expensive SQL</h3>";
00654                         $s .= $this->tohtml($rs,'expeixora');
00655                 }
00656         
00657                 return $s;
00658         }
00659         
00660         function clearsql() 
00661         {
00662                 $perf_table = adodb_perf::table();
00663         // using the naive "delete from $perf_table where created<".$this->conn->sysTimeStamp will cause the table to lock, possibly
00664         // for a long time
00665                 $sql = 
00666 "DECLARE cnt pls_integer;
00667 BEGIN
00668         cnt := 0;
00669         FOR rec IN (SELECT ROWID AS rr FROM $perf_table WHERE created<SYSDATE) 
00670         LOOP
00671           cnt := cnt + 1;
00672           DELETE FROM $perf_table WHERE ROWID=rec.rr;
00673           IF cnt = 1000 THEN
00674                 COMMIT;
00675                 cnt := 0;
00676           END IF;
00677         END LOOP;
00678         commit;
00679 END;";
00680 
00681                 $ok = $this->conn->Execute($sql);
00682         }
00683         
00684 }
00685 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations