如何定位mysql 是哪个sql执行语句慢

  • Post author:
  • Post category:mysql




如题,利用MySQL的performance schema 用于监控MySQL server在一个较低级别的运行过程中的资源消耗、资源等待等情况。



直接上代码

public function getSqlData($explain, $combine){
		self::$db->select_db('performance_schema');
		$sql = "select * from events_statements_current";
		$rs = self::$db->query($sql);
		$data = $summary = [];
		while ( $r = self::$db->fetch_array($rs) ){
			if ( empty($r['SQL_TEXT']) 
				|| strpos($r['SQL_TEXT'],'events_statements_current') !== false
				|| strpos($r['SQL_TEXT'],'BEGIN') !== false ) continue;
				
			$r['DIY_TEXT'] = $this->formatSql($r['SQL_TEXT'], $r['DIGEST_TEXT'], $combine);
			$r['DIGEST'] = md5($r['DIY_TEXT']);
			$data[] = $r;
			
			$this->defineSummary($summary, $r['DIGEST']);
			$summary[$r['DIGEST']]['sql_cnt']++;
			$summary[$r['DIGEST']]['run_time'] += $r['TIMER_WAIT'];
			$summary[$r['DIGEST']]['lock_time'] += $r['LOCK_TIME'];
			$summary[$r['DIGEST']]['rows_sent'] += $r['ROWS_SENT'];
			$summary[$r['DIGEST']]['rows_examined'] += $r['ROWS_EXAMINED'];
			$summary[$r['DIGEST']]['rows_affected'] += $r['ROWS_AFFECTED'];
			$summary[$r['DIGEST']]['warnings'] += $r['WARNINGS'];
			$summary[$r['DIGEST']]['tmp_disk_table'] += $r['CREATED_TMP_DISK_TABLES'];
			$summary[$r['DIGEST']]['tmp_table'] += $r['CREATED_TMP_TABLES'];
			$summary[$r['DIGEST']]['no_index'] += $r['NO_INDEX_USED'];
			
			if ( !isset($summary[$r['DIGEST']]['sql']) ) $summary[$r['DIGEST']]['sql'] = $r['SQL_TEXT'];
			if ( !isset($summary[$r['DIGEST']]['event']) ) $summary[$r['DIGEST']]['event'] = explode('/',$r['EVENT_NAME'])[2];
			if ( !isset($summary[$r['DIGEST']]['schema']) ) $summary[$r['DIGEST']]['schema'] = $r['CURRENT_SCHEMA'];
			
			if ( DEBUG_TYPE == 'rogue' ){
				if ( !isset($summary[$r['DIGEST']]['debug']) ) $summary[$r['DIGEST']]['debug'] = [];
				if ( !isset($summary[$r['DIGEST']]['debug']['sql_text']) || empty($summary[$r['DIGEST']]['debug']['sql_text']) ) $summary[$r['DIGEST']]['debug']['sql_text'] = $r['DIY_TEXT'];
				if ( !isset($summary[$r['DIGEST']]['debug']['digest_text']) || empty($summary[$r['DIGEST']]['debug']['digest_text']) ) $summary[$r['DIGEST']]['debug']['digest_text'] = $r['DIGEST_TEXT'];
			}
		}
		
		rsort_by($summary, 'run_time');		
		foreach ( $summary as $k => $v ){
			$summary[$k]['run_time'] = self::_unitPico($v['run_time']);
			$summary[$k]['lock_time'] = self::_unitPico($v['lock_time']);
			if ( is_numeric(substr($summary[$k]['run_time'], -2, 1)) )  $summary[$k]['run_time'] = red(b($summary[$k]['run_time']));
			if ( $summary[$k]['warnings'] > 0 ) $summary[$k]['warnings'] = red(b($v['warnings']));
			if ( $summary[$k]['tmp_disk_table'] > 0 ) $summary[$k]['tmp_disk_table'] = red(b($v['tmp_disk_table']));
			if ( $summary[$k]['tmp_table'] > 0 ) $summary[$k]['tmp_table'] = red(b($v['tmp_table']));
			if ( $summary[$k]['no_index'] > 0 ) $summary[$k]['no_index'] = red(b($v['no_index']));
			
			
			#explain信息
			if ( $explain == 1 ){
				if ( substr($v['sql'],-3,3) == '...' || stripos($v['sql'], 'select ') !== 0 ) continue;
				self::$db->change_user($GLOBALS['_DBReadOnlyUser']['name'], $GLOBALS['_DBReadOnlyUser']['password'], $v['schema']);
				
				$sql = 'explain '.$v['sql'];
				$rs = self::$db->query($sql);
				$exp = array();
				while ($r = self::$db->fetch_array($rs)){
					$exp[] = $r;
				}
				$summary[$k]['explain'] = $exp;
			}
		}
	
		return $summary;
	}



版权声明:本文为qq_39999924原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。