You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							499 lines
						
					
					
						
							16 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							499 lines
						
					
					
						
							16 KiB
						
					
					
				
								<?php
							 | 
						|
								/* 
							 | 
						|
								V4.55 3 Jan 2005  (c) 2000-2005 John Lim (jlim@natsoft.com.my). All rights reserved.
							 | 
						|
								  Released under both BSD license and Lesser GPL library license. 
							 | 
						|
								  Whenever there is any discrepancy between the two licenses, 
							 | 
						|
								  the BSD license will take precedence. See License.txt. 
							 | 
						|
								  Set tabs to 4 for best viewing.
							 | 
						|
								  
							 | 
						|
								  Latest version is available at http://adodb.sourceforge.net
							 | 
						|
								  
							 | 
						|
								  Library for basic performance monitoring and tuning 
							 | 
						|
								  
							 | 
						|
								*/
							 | 
						|
								
							 | 
						|
								// security - hide paths
							 | 
						|
								if (!defined('ADODB_DIR')) die();
							 | 
						|
								
							 | 
						|
								class perf_oci8 extends ADODB_perf{
							 | 
						|
									
							 | 
						|
									var $tablesSQL = "select segment_name as \"tablename\", sum(bytes)/1024 as \"size_in_k\",tablespace_name as \"tablespace\",count(*) \"extents\" from sys.user_extents 
							 | 
						|
									   group by segment_name,tablespace_name";
							 | 
						|
									 
							 | 
						|
									var $version;
							 | 
						|
									var $createTableSQL = "CREATE TABLE adodb_logsql (
							 | 
						|
										  created date NOT NULL,
							 | 
						|
										  sql0 varchar(250) NOT NULL,
							 | 
						|
										  sql1 varchar(4000) NOT NULL,
							 | 
						|
										  params varchar(4000),
							 | 
						|
										  tracer varchar(4000),
							 | 
						|
										  timer decimal(16,6) NOT NULL
							 | 
						|
										)";
							 | 
						|
									
							 | 
						|
									var $settings = array(
							 | 
						|
									'Ratios',
							 | 
						|
										'data cache hit ratio' => array('RATIOH',
							 | 
						|
											"select round((1-(phy.value / (cur.value + con.value)))*100,2) 
							 | 
						|
											from v\$sysstat cur, v\$sysstat con, v\$sysstat phy
							 | 
						|
											where cur.name = 'db block gets' and
							 | 
						|
											      con.name = 'consistent gets' and
							 | 
						|
											      phy.name = 'physical reads'",
							 | 
						|
											'=WarnCacheRatio'),
							 | 
						|
										
							 | 
						|
										'sql cache hit ratio' => array( 'RATIOH',
							 | 
						|
											'select round(100*(sum(pins)-sum(reloads))/sum(pins),2)  from v$librarycache',
							 | 
						|
											'increase <i>shared_pool_size</i> if too ratio low'),
							 | 
						|
											
							 | 
						|
										'datadict cache hit ratio' => array('RATIOH',
							 | 
						|
										"select      
							 | 
						|
								           round((1 - (sum(getmisses) / (sum(gets) +          
							 | 
						|
								   		 sum(getmisses))))*100,2)
							 | 
						|
										from  v\$rowcache",
							 | 
						|
										'increase <i>shared_pool_size</i> if too ratio low'),
							 | 
						|
										
							 | 
						|
										'memory sort ratio' => array('RATIOH',
							 | 
						|
										"SELECT ROUND((100 * b.VALUE) /DECODE ((a.VALUE + b.VALUE), 
							 | 
						|
								       0,1,(a.VALUE + b.VALUE)),2)
							 | 
						|
								FROM   v\$sysstat a, 
							 | 
						|
								       v\$sysstat b
							 | 
						|
								WHERE  a.name = 'sorts (disk)'
							 | 
						|
								AND    b.name = 'sorts (memory)'",
							 | 
						|
									"% of memory sorts compared to disk sorts - should be over 95%"),
							 | 
						|
								
							 | 
						|
									'IO',
							 | 
						|
										'data reads' => array('IO',
							 | 
						|
										"select value from v\$sysstat where name='physical reads'"),
							 | 
						|
									
							 | 
						|
									'data writes' => array('IO',
							 | 
						|
										"select value from v\$sysstat where name='physical writes'"),
							 | 
						|
									
							 | 
						|
									'Data Cache',
							 | 
						|
										'data cache buffers' => array( 'DATAC',
							 | 
						|
										"select a.value/b.value  from v\$parameter a, v\$parameter b 
							 | 
						|
											where a.name = 'db_cache_size' and b.name= 'db_block_size'",
							 | 
						|
											'Number of cache buffers. Tune <i>db_cache_size</i> if the <i>data cache hit ratio</i> is too low.'),
							 | 
						|
										'data cache blocksize' => array('DATAC',
							 | 
						|
											"select value from v\$parameter where name='db_block_size'",
							 | 
						|
											'' ),			
							 | 
						|
									'Memory Pools',
							 | 
						|
										'data cache size' => array('DATAC',
							 | 
						|
											"select value from v\$parameter where name = 'db_cache_size'",
							 | 
						|
											'db_cache_size' ),
							 | 
						|
										'shared pool size' => array('DATAC',
							 | 
						|
											"select value from v\$parameter where name = 'shared_pool_size'",
							 | 
						|
											'shared_pool_size, which holds shared sql, stored procedures, dict cache and similar shared structs' ),
							 | 
						|
										'java pool size' => array('DATAJ',
							 | 
						|
											"select value from v\$parameter where name = 'java_pool_size'",
							 | 
						|
											'java_pool_size' ),
							 | 
						|
										'large pool buffer size' => array('CACHE',
							 | 
						|
											"select value from v\$parameter where name='large_pool_size'",
							 | 
						|
											'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) ' ),
							 | 
						|
								
							 | 
						|
										'pga buffer size' => array('CACHE',			
							 | 
						|
											"select value from v\$parameter where name='pga_aggregate_target'",
							 | 
						|
											'program global area is private memory for sorting, and hash and bitmap merges - since oracle 9i (pga_aggregate_target)' ),
							 | 
						|
								
							 | 
						|
										
							 | 
						|
										'Connections',
							 | 
						|
										'current connections' => array('SESS',
							 | 
						|
											'select count(*) from sys.v_$session where username is not null',
							 | 
						|
											''),
							 | 
						|
										'max connections' => array( 'SESS',
							 | 
						|
											"select value from v\$parameter where name='sessions'",
							 | 
						|
											''),
							 | 
						|
								
							 | 
						|
									'Memory Utilization',		
							 | 
						|
										'data cache utilization ratio' => array('RATIOU',
							 | 
						|
											"select round((1-bytes/sgasize)*100, 2)
							 | 
						|
											from (select sum(bytes) sgasize from sys.v_\$sgastat) s, sys.v_\$sgastat f
							 | 
						|
											where name = 'free memory' and pool = 'shared pool'",
							 | 
						|
										'Percentage of data cache actually in use - should be over 85%'),
							 | 
						|
										
							 | 
						|
										'shared pool utilization ratio' => array('RATIOU',
							 | 
						|
										'select round((sga.bytes/p.value)*100,2)
							 | 
						|
										from v$sgastat sga, v$parameter p
							 | 
						|
										where sga.name = \'free memory\' and sga.pool = \'shared pool\'
							 | 
						|
										and p.name = \'shared_pool_size\'',
							 | 
						|
										'Percentage of shared pool actually used - too low is bad, too high is worse'),
							 | 
						|
										
							 | 
						|
										'large pool utilization ratio' => array('RATIOU',
							 | 
						|
											"select round((1-bytes/sgasize)*100, 2)
							 | 
						|
											from (select sum(bytes) sgasize from sys.v_\$sgastat) s, sys.v_\$sgastat f
							 | 
						|
											where name = 'free memory' and pool = 'large pool'",
							 | 
						|
										'Percentage of large_pool actually in use - too low is bad, too high is worse'),
							 | 
						|
										'sort buffer size' => array('CACHE',
							 | 
						|
											"select value from v\$parameter where name='sort_area_size'",
							 | 
						|
											'max in-mem sort_area_size (per query), uses memory in pga' ),
							 | 
						|
								
							 | 
						|
										'pga usage at peak' => array('RATIOU',
							 | 
						|
										'=PGA','Mb utilization at peak transactions (requires Oracle 9i+)'),
							 | 
						|
									'Transactions',
							 | 
						|
										'rollback segments' => array('ROLLBACK',
							 | 
						|
											"select count(*) from sys.v_\$rollstat",
							 | 
						|
											''),
							 | 
						|
									
							 | 
						|
										'peak transactions' => array('ROLLBACK',
							 | 
						|
											"select max_utilization  tx_hwm
							 | 
						|
								    		from sys.v_\$resource_limit
							 | 
						|
								    		where resource_name = 'transactions'",
							 | 
						|
											'Taken from high-water-mark'),
							 | 
						|
										'max transactions' => array('ROLLBACK',
							 | 
						|
											"select value from v\$parameter where name = 'transactions'",
							 | 
						|
											'max transactions / rollback segments < 3.5 (or transactions_per_rollback_segment)'),
							 | 
						|
									'Parameters',	
							 | 
						|
										'cursor sharing' => array('CURSOR',
							 | 
						|
											"select value from v\$parameter where name = 'cursor_sharing'",
							 | 
						|
											'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>.'),
							 | 
						|
										/*
							 | 
						|
										'cursor reuse' => array('CURSOR',
							 | 
						|
											"select count(*) from (select sql_text_wo_constants, count(*)
							 | 
						|
								  from t1
							 | 
						|
								 group by sql_text_wo_constants
							 | 
						|
								having count(*) > 100)",'These are sql statements that should be using bind variables'),*/
							 | 
						|
										'index cache cost' => array('COST',
							 | 
						|
											"select value from v\$parameter where name = 'optimizer_index_caching'",
							 | 
						|
											'=WarnIndexCost'),
							 | 
						|
										'random page cost' => array('COST',
							 | 
						|
											"select value from v\$parameter where name = 'optimizer_index_cost_adj'",
							 | 
						|
											'=WarnPageCost'),
							 | 
						|
										
							 | 
						|
										false
							 | 
						|
										
							 | 
						|
									);
							 | 
						|
									
							 | 
						|
									
							 | 
						|
									function perf_oci8(&$conn)
							 | 
						|
									{
							 | 
						|
										$savelog = $conn->LogSQL(false);	
							 | 
						|
										$this->version = $conn->ServerInfo();
							 | 
						|
										$conn->LogSQL($savelog);	
							 | 
						|
										$this->conn =& $conn;
							 | 
						|
									}
							 | 
						|
									
							 | 
						|
									function WarnPageCost($val)
							 | 
						|
									{
							 | 
						|
										if ($val == 100) $s = '<font color=red><b>Too High</b>. </font>';
							 | 
						|
										else $s = '';
							 | 
						|
										
							 | 
						|
										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>. ';
							 | 
						|
									}
							 | 
						|
									
							 | 
						|
									function WarnIndexCost($val)
							 | 
						|
									{
							 | 
						|
										if ($val == 0) $s = '<font color=red><b>Too Low</b>. </font>';
							 | 
						|
										else $s = '';
							 | 
						|
										
							 | 
						|
										return $s.'Percentage of indexed data blocks expected in the cache.
							 | 
						|
											Recommended is 20 (fast disk array) to 50 (slower hard disks). Default is 0.
							 | 
						|
											 See <a href=http://www.dba-oracle.com/oracle_tips_cbo_part1.htm>optimizer_index_caching</a>.';
							 | 
						|
										}
							 | 
						|
									
							 | 
						|
									function PGA()
							 | 
						|
									{
							 | 
						|
										if ($this->version['version'] < 9) return 'Oracle 9i or later required';
							 | 
						|
										
							 | 
						|
										$rs = $this->conn->Execute("select a.mb,a.targ as pga_size_pct,a.pct from 
							 | 
						|
									   (select round(pga_target_for_estimate/1024.0/1024.0,0) Mb,
							 | 
						|
									   	   pga_target_factor targ,estd_pga_cache_hit_percentage pct,rownum as r 
							 | 
						|
									   	   from v\$pga_target_advice) a left join
							 | 
						|
									   (select round(pga_target_for_estimate/1024.0/1024.0,0) Mb,
							 | 
						|
									   	   pga_target_factor targ,estd_pga_cache_hit_percentage pct,rownum as r 
							 | 
						|
									   	   from v\$pga_target_advice) b on 
							 | 
						|
									  a.r = b.r+1 where 
							 | 
						|
								  		b.pct < 100");
							 | 
						|
										if (!$rs) return "Only in 9i or later";
							 | 
						|
										$rs->Close();
							 | 
						|
										if ($rs->EOF) return "PGA could be too big";
							 | 
						|
										
							 | 
						|
										return reset($rs->fields);
							 | 
						|
									}
							 | 
						|
									
							 | 
						|
									function Explain($sql,$partial=false) 
							 | 
						|
									{
							 | 
						|
										$savelog = $this->conn->LogSQL(false);
							 | 
						|
										$rs =& $this->conn->SelectLimit("select ID FROM PLAN_TABLE");
							 | 
						|
										if (!$rs) {
							 | 
						|
											echo "<p><b>Missing PLAN_TABLE</b></p>
							 | 
						|
								<pre>
							 | 
						|
								CREATE TABLE PLAN_TABLE (
							 | 
						|
								  STATEMENT_ID                    VARCHAR2(30),
							 | 
						|
								  TIMESTAMP                       DATE,
							 | 
						|
								  REMARKS                         VARCHAR2(80),
							 | 
						|
								  OPERATION                       VARCHAR2(30),
							 | 
						|
								  OPTIONS                         VARCHAR2(30),
							 | 
						|
								  OBJECT_NODE                     VARCHAR2(128),
							 | 
						|
								  OBJECT_OWNER                    VARCHAR2(30),
							 | 
						|
								  OBJECT_NAME                     VARCHAR2(30),
							 | 
						|
								  OBJECT_INSTANCE                 NUMBER(38),
							 | 
						|
								  OBJECT_TYPE                     VARCHAR2(30),
							 | 
						|
								  OPTIMIZER                       VARCHAR2(255),
							 | 
						|
								  SEARCH_COLUMNS                  NUMBER,
							 | 
						|
								  ID                              NUMBER(38),
							 | 
						|
								  PARENT_ID                       NUMBER(38),
							 | 
						|
								  POSITION                        NUMBER(38),
							 | 
						|
								  COST                            NUMBER(38),
							 | 
						|
								  CARDINALITY                     NUMBER(38),
							 | 
						|
								  BYTES                           NUMBER(38),
							 | 
						|
								  OTHER_TAG                       VARCHAR2(255),
							 | 
						|
								  PARTITION_START                 VARCHAR2(255),
							 | 
						|
								  PARTITION_STOP                  VARCHAR2(255),
							 | 
						|
								  PARTITION_ID                    NUMBER(38),
							 | 
						|
								  OTHER                           LONG,
							 | 
						|
								  DISTRIBUTION                    VARCHAR2(30)
							 | 
						|
								);
							 | 
						|
								</pre>";
							 | 
						|
											return false;
							 | 
						|
										}
							 | 
						|
										
							 | 
						|
										$rs->Close();
							 | 
						|
									//	$this->conn->debug=1;
							 | 
						|
									
							 | 
						|
										if ($partial) {
							 | 
						|
											$sqlq = $this->conn->qstr($sql.'%');
							 | 
						|
											$arr = $this->conn->GetArray("select distinct distinct sql1 from adodb_logsql where sql1 like $sqlq");
							 | 
						|
											if ($arr) {
							 | 
						|
												foreach($arr as $row) {
							 | 
						|
													$sql = reset($row);
							 | 
						|
													if (crc32($sql) == $partial) break;
							 | 
						|
												}
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
										
							 | 
						|
										$s = "<p><b>Explain</b>: ".htmlspecialchars($sql)."</p>";	
							 | 
						|
										
							 | 
						|
										$this->conn->BeginTrans();
							 | 
						|
										$id = "ADODB ".microtime();
							 | 
						|
										$rs =& $this->conn->Execute("EXPLAIN PLAN SET STATEMENT_ID='$id' FOR $sql");
							 | 
						|
										$m = $this->conn->ErrorMsg();
							 | 
						|
										if ($m) {
							 | 
						|
											$this->conn->RollbackTrans();
							 | 
						|
											$this->conn->LogSQL($savelog);
							 | 
						|
											$s .= "<p>$m</p>";
							 | 
						|
											return $s;
							 | 
						|
										}
							 | 
						|
										$rs = $this->conn->Execute("
							 | 
						|
										select 
							 | 
						|
								  '<pre>'||lpad('--', (level-1)*2,'-') || trim(operation) || ' ' || trim(options)||'</pre>'  as Operation, 
							 | 
						|
								  object_name,COST,CARDINALITY,bytes
							 | 
						|
										FROM plan_table 
							 | 
						|
								START WITH id = 0  and STATEMENT_ID='$id'  
							 | 
						|
								CONNECT BY prior id=parent_id and statement_id='$id'");
							 | 
						|
										
							 | 
						|
										$s .= rs2html($rs,false,false,false,false);
							 | 
						|
										$this->conn->RollbackTrans();
							 | 
						|
										$this->conn->LogSQL($savelog);
							 | 
						|
										$s .= $this->Tracer($sql,$partial);
							 | 
						|
										return $s;
							 | 
						|
									}
							 | 
						|
									
							 | 
						|
									
							 | 
						|
									function CheckMemory()
							 | 
						|
									{
							 | 
						|
										if ($this->version['version'] < 9) return 'Oracle 9i or later required';
							 | 
						|
										
							 | 
						|
										 $rs =& $this->conn->Execute("
							 | 
						|
								select  a.size_for_estimate as cache_mb_estimate,
							 | 
						|
									case when a.size_factor=1 then 
							 | 
						|
								   		'<<= current'
							 | 
						|
									 when a.estd_physical_read_factor-b.estd_physical_read_factor > 0 and a.estd_physical_read_factor<1 then
							 | 
						|
										'- BETTER - '
							 | 
						|
									else ' ' end as currsize, 
							 | 
						|
								   a.estd_physical_read_factor-b.estd_physical_read_factor as best_when_0
							 | 
						|
								   from (select size_for_estimate,size_factor,estd_physical_read_factor,rownum  r from v\$db_cache_advice) a , 
							 | 
						|
								   (select size_for_estimate,size_factor,estd_physical_read_factor,rownum r from v\$db_cache_advice) b where a.r = b.r-1");
							 | 
						|
										if (!$rs) return false;
							 | 
						|
										
							 | 
						|
										/*
							 | 
						|
										The v$db_cache_advice utility show the marginal changes in physical data block reads for different sizes of db_cache_size
							 | 
						|
										*/
							 | 
						|
										$s = "<h3>Data Cache Estimate</h3>";
							 | 
						|
										if ($rs->EOF) {
							 | 
						|
											$s .= "<p>Cache that is 50% of current size is still too big</p>";
							 | 
						|
										} else {
							 | 
						|
											$s .= "Ideal size of Data Cache is when \"best_when_0\" changes from a positive number and becomes zero.";
							 | 
						|
											$s .= rs2html($rs,false,false,false,false);
							 | 
						|
										}
							 | 
						|
										return $s;
							 | 
						|
									}
							 | 
						|
									
							 | 
						|
									/*
							 | 
						|
										Generate html for suspicious/expensive sql
							 | 
						|
									*/
							 | 
						|
									function tohtml(&$rs,$type)
							 | 
						|
									{
							 | 
						|
										$o1 = $rs->FetchField(0);
							 | 
						|
										$o2 = $rs->FetchField(1);
							 | 
						|
										$o3 = $rs->FetchField(2);
							 | 
						|
										if ($rs->EOF) return '<p>None found</p>';
							 | 
						|
										$check = '';
							 | 
						|
										$sql = '';
							 | 
						|
										$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>';
							 | 
						|
										while (!$rs->EOF) {
							 | 
						|
											if ($check != $rs->fields[0].'::'.$rs->fields[1]) {
							 | 
						|
												if ($check) {
							 | 
						|
													$carr = explode('::',$check);
							 | 
						|
													$prefix = "<a href=\"?$type=1&sql=".rawurlencode($sql).'&x#explain">';
							 | 
						|
													$suffix = '</a>';
							 | 
						|
													if (strlen($prefix)>2000) {
							 | 
						|
														$prefix = '';
							 | 
						|
														$suffix = '';
							 | 
						|
													}
							 | 
						|
													
							 | 
						|
													$s .=  "\n<tr><td align=right>".$carr[0].'</td><td align=right>'.$carr[1].'</td><td>'.$prefix.$sql.$suffix.'</td></tr>';
							 | 
						|
												}
							 | 
						|
												$sql = $rs->fields[2];
							 | 
						|
												$check = $rs->fields[0].'::'.$rs->fields[1];			
							 | 
						|
											} else
							 | 
						|
												$sql .= $rs->fields[2];
							 | 
						|
											
							 | 
						|
											$rs->MoveNext();
							 | 
						|
										}
							 | 
						|
										$rs->Close();
							 | 
						|
										
							 | 
						|
										$carr = explode('::',$check);
							 | 
						|
										$prefix = "<a target=".rand()." href=\"?&hidem=1&$type=1&sql=".rawurlencode($sql).'&x#explain">';
							 | 
						|
										$suffix = '</a>';
							 | 
						|
										if (strlen($prefix)>2000) {
							 | 
						|
											$prefix = '';
							 | 
						|
											$suffix = '';
							 | 
						|
										}
							 | 
						|
										$s .=  "\n<tr><td align=right>".$carr[0].'</td><td align=right>'.$carr[1].'</td><td>'.$prefix.$sql.$suffix.'</td></tr>';
							 | 
						|
													
							 | 
						|
										return $s."</table>\n\n";
							 | 
						|
									}
							 | 
						|
									
							 | 
						|
									// code thanks to Ixora. 
							 | 
						|
									// http://www.ixora.com.au/scripts/query_opt.htm
							 | 
						|
									// requires oracle 8.1.7 or later
							 | 
						|
									function SuspiciousSQL($numsql=10)
							 | 
						|
									{
							 | 
						|
										$sql = "
							 | 
						|
								select
							 | 
						|
								  substr(to_char(s.pct, '99.00'), 2) || '%'  load,
							 | 
						|
								  s.executions  executes,
							 | 
						|
								  p.sql_text
							 | 
						|
								from
							 | 
						|
								  ( 
							 | 
						|
								    select
							 | 
						|
								      address,
							 | 
						|
								      buffer_gets,
							 | 
						|
								      executions,
							 | 
						|
								      pct,
							 | 
						|
								      rank() over (order by buffer_gets desc)  ranking
							 | 
						|
								    from
							 | 
						|
								      ( 
							 | 
						|
									select
							 | 
						|
									  address,
							 | 
						|
									  buffer_gets,
							 | 
						|
									  executions,
							 | 
						|
									  100 * ratio_to_report(buffer_gets) over ()  pct
							 | 
						|
									from
							 | 
						|
									  sys.v_\$sql
							 | 
						|
									where
							 | 
						|
									  command_type != 47 and module != 'T.O.A.D.'
							 | 
						|
								      )
							 | 
						|
								    where
							 | 
						|
								      buffer_gets > 50 * executions
							 | 
						|
								  )  s,
							 | 
						|
								  sys.v_\$sqltext  p
							 | 
						|
								where
							 | 
						|
								  s.ranking <= $numsql and
							 | 
						|
								  p.address = s.address
							 | 
						|
								order by
							 | 
						|
								  1 desc, s.address, p.piece";
							 | 
						|
								
							 | 
						|
								  		global $ADODB_CACHE_MODE,$HTTP_GET_VARS;
							 | 
						|
								  		if (isset($HTTP_GET_VARS['expsixora']) && isset($HTTP_GET_VARS['sql'])) {
							 | 
						|
												$partial = empty($HTTP_GET_VARS['part']);
							 | 
						|
												echo "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
							 | 
						|
										}
							 | 
						|
								
							 | 
						|
										if (isset($HTTP_GET_VARS['sql'])) return $this->_SuspiciousSQL();
							 | 
						|
										
							 | 
						|
										$save = $ADODB_CACHE_MODE;
							 | 
						|
										$ADODB_CACHE_MODE = ADODB_FETCH_NUM;
							 | 
						|
										$savelog = $this->conn->LogSQL(false);
							 | 
						|
										$rs =& $this->conn->SelectLimit($sql);
							 | 
						|
										$this->conn->LogSQL($savelog);
							 | 
						|
										$ADODB_CACHE_MODE = $save;
							 | 
						|
										if ($rs) {
							 | 
						|
											$s = "\n<h3>Ixora Suspicious SQL</h3>";
							 | 
						|
											$s .= $this->tohtml($rs,'expsixora');
							 | 
						|
										} else 
							 | 
						|
											$s = '';
							 | 
						|
										
							 | 
						|
										if ($s) $s .= '<p>';
							 | 
						|
										$s .= $this->_SuspiciousSQL();
							 | 
						|
										return $s;
							 | 
						|
									}
							 | 
						|
									
							 | 
						|
									// code thanks to Ixora. 
							 | 
						|
									// http://www.ixora.com.au/scripts/query_opt.htm
							 | 
						|
									// requires oracle 8.1.7 or later
							 | 
						|
									function ExpensiveSQL($numsql = 10)
							 | 
						|
									{
							 | 
						|
										$sql = "
							 | 
						|
								select
							 | 
						|
								  substr(to_char(s.pct, '99.00'), 2) || '%'  load,
							 | 
						|
								  s.executions  executes,
							 | 
						|
								  p.sql_text
							 | 
						|
								from
							 | 
						|
								  ( 
							 | 
						|
								    select
							 | 
						|
								      address,
							 | 
						|
								      disk_reads,
							 | 
						|
								      executions,
							 | 
						|
								      pct,
							 | 
						|
								      rank() over (order by disk_reads desc)  ranking
							 | 
						|
								    from
							 | 
						|
								      (
							 | 
						|
									select
							 | 
						|
									  address,
							 | 
						|
									  disk_reads,
							 | 
						|
									  executions,
							 | 
						|
									  100 * ratio_to_report(disk_reads) over ()  pct
							 | 
						|
									from
							 | 
						|
									  sys.v_\$sql
							 | 
						|
									where
							 | 
						|
									  command_type != 47 and module != 'T.O.A.D.'
							 | 
						|
								      )
							 | 
						|
								    where
							 | 
						|
								      disk_reads > 50 * executions
							 | 
						|
								  )  s,
							 | 
						|
								  sys.v_\$sqltext  p
							 | 
						|
								where
							 | 
						|
								  s.ranking <= $numsql and
							 | 
						|
								  p.address = s.address
							 | 
						|
								order by
							 | 
						|
								  1 desc, s.address, p.piece
							 | 
						|
								";
							 | 
						|
										global $ADODB_CACHE_MODE,$HTTP_GET_VARS;
							 | 
						|
								  		if (isset($HTTP_GET_VARS['expeixora']) && isset($HTTP_GET_VARS['sql'])) {
							 | 
						|
											$partial = empty($HTTP_GET_VARS['part']);	
							 | 
						|
											echo "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
							 | 
						|
										}
							 | 
						|
										
							 | 
						|
										if (isset($HTTP_GET_VARS['sql'])) {
							 | 
						|
											 $var =& $this->_ExpensiveSQL();
							 | 
						|
											 return $var;
							 | 
						|
										}
							 | 
						|
										$save = $ADODB_CACHE_MODE;
							 | 
						|
										$ADODB_CACHE_MODE = ADODB_FETCH_NUM;
							 | 
						|
										$savelog = $this->conn->LogSQL(false);
							 | 
						|
										$rs =& $this->conn->Execute($sql);
							 | 
						|
										$this->conn->LogSQL($savelog);
							 | 
						|
										$ADODB_CACHE_MODE = $save;
							 | 
						|
										if ($rs) {
							 | 
						|
											$s = "\n<h3>Ixora Expensive SQL</h3>";
							 | 
						|
											$s .= $this->tohtml($rs,'expeixora');
							 | 
						|
										} else 
							 | 
						|
											$s = '';
							 | 
						|
										
							 | 
						|
										
							 | 
						|
										if ($s) $s .= '<p>';
							 | 
						|
										$s .= $this->_ExpensiveSQL();
							 | 
						|
										return $s;
							 | 
						|
									}
							 | 
						|
									
							 | 
						|
								}
							 | 
						|
								?>
							 |