sub EXPLAIN_queries
{
d("EXPLAIN_queries\n") if $op{debug};
my $q_h = shift;
my $row;
my @rows;
my $col;
my ($x, $q);
my ($i, $j);
my $select_query;
connect_to_MySQL();
foreach $q (keys %$q_h)
{
$x = $$q_h{$q};
$x->{EXPLAIN_err} = 0;
$x->{rp} = -1;
$x->{rr} = -1;
if($x->{sample} !~ /^SELECT/i)
{
my $qr = new QueryRewriter;
$select_query = $qr->convert_to_select($x->{sample});
if ( $select_query !~ /^SELECT/i ) {
$x->{EXPLAIN_err} = "Cannot convert to a SELECT statement";
next;
}
}
else {
$select_query = $x->{sample};
}
if(!$x->{db})
{
if(!$op{db})
{
eval {
$query = $dbh->prepare("EXPLAIN $select_query");
$query->execute();
};
if ( $EVAL_ERROR ) {
$x->{EXPLAIN_err} = "Unknown database and no qualified table names";
next;
}
else {
goto PARSE_EXPLAIN;
}
}
else
{
foreach(keys %db)
{
$dbh->do("USE $_;");
$query = $dbh->prepare("EXPLAIN $select_query");
$query->execute();
next if $DBI::err;
$x->{db} = $_;
last;
}
if(!$x->{db})
{
$x->{EXPLAIN_err} = "Unknown database and no given databases work";
next;
}
}
}
$query = $dbh->prepare("USE $x->{db};");
$query->execute();
$x->{EXPLAIN_err} = $DBI::errstr and next if $DBI::err;
$query = $dbh->prepare("EXPLAIN $select_query");
$query->execute();
$x->{EXPLAIN_err} = $DBI::errstr and next if $DBI::err;
PARSE_EXPLAIN:
$x->{EXPLAIN} = [] if $op{ex};
$x->{tcount} = '' if $extras{tcount};
$x->{TSCHEMA} = [] if $extras{tschema};
while($row = $query->fetchrow_hashref())
{
push @rows, ($row->{rows} ? $row->{rows} : 0)
if $op{ex};
for($j = 0; $j < $query->{NUM_OF_FIELDS}; $j++)
{
$col = $query->{NAME}->[$j];
if ( $op{ex} ) {
push @{$x->{EXPLAIN}}, $col;
push @{$x->{EXPLAIN}}, ($row->{$col} ? $row->{$col} : '');
}
}
}
if ( $op{ex} ) {
for($i = 0, $j = 1; $i < $query->rows; $i++) { $j *= $rows[$i]; }
$x->{rp} = $j;
$x->{rr} = calc_rows_read(\@rows);
}
if ( $extras{tcount} || $extras{tschema} ) {
my $tbls = parse_table_aliases(get_table_ref($select_query));
foreach my $tbl ( keys %$tbls ) {
next if $tbl eq 'DATABASE';
my $db = $x->{db};
if ( exists $tbls->{DATABASE}
&& exists $tbls->{DATABASE}->{$tbl} ) {
$db = $tbls->{DATABASE}->{$tbl};
}
if ( $extras{tcount} ) {
my $n = make_short(get_row_count($dbh, $db, $tbls->{$tbl}));
$x->{tcount} .= "$tbls->{$tbl}:$n ";
}
if ( $extras{tschema} ) {
my $ddl = get_create_table($dbh, $db, $tbls->{$tbl});
if ( $ddl ) {
push @{$x->{TSCHEMA}},
($ddl->[0] eq 'view' ? '(VIEW) ' : '')
. $ddl->[1];
}
else {
$x->{TSCHEMA} = 'Could not get table schemas';
}
}
}
}
}
}
* 这里,如果指定了-ex,那么mysqlsla 会主动连接mysql,用户名,密码,主机当然都是你提供的。然后重写SQL语句QueryRewriter,将非select语句,全部转换成SELECT子句。并且根据explain的结果进行分析,最终report到client。