Created
October 27, 2011 16:38
-
-
Save justinrainbow/1320078 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# | |
# Nathanial Hendler | |
# http://retards.org/ | |
# | |
# 2001-06-26 v1.0 | |
# | |
# This perl script parses a MySQL slow_queries log file | |
# ignoring all queries less than $min_time and prints | |
# out how many times a query was greater than $min_time | |
# with the seconds it took each time to run. The queries | |
# are sorted by number of times it took; the most often | |
# query appearing at the bottom of the output. | |
# | |
# Usage: mysql_slow_log_parser logfile | |
# | |
# ------------------------ | |
# SOMETHING TO THINK ABOUT (aka: how to read output) | |
# ------------------------ | |
# | |
# Also, it does to regex substitutions to normalize | |
# the queries... | |
# | |
# $query_string =~ s/\d+/XXX/g; | |
# $query_string =~ s/([\'\"]).+?([\'\"])/$1XXX$2/g; | |
# | |
# These replace numbers with XXX and strings found in | |
# quotes with XXX so that the same select statement | |
# with different WHERE clauses will be considered | |
# as the same query. | |
# | |
# so these... | |
# | |
# SELECT * FROM offices WHERE office_id = 3; | |
# SELECT * FROM offices WHERE office_id = 19; | |
# | |
# become... | |
# | |
# SELECT * FROM offices WHERE office_id = XXX; | |
# | |
# | |
# And these... | |
# | |
# SELECT * FROM photos WHERE camera_model LIKE 'Nikon%'; | |
# SELECT * FROM photos WHERE camera_model LIKE '%Olympus'; | |
# | |
# become... | |
# | |
# SELECT * FROM photos WHERE camera_model LIKE 'XXX'; | |
# | |
# | |
# --------------------- | |
# THIS MAY BE IMPORTANT (aka: Probably Not) | |
# --------------------- | |
# | |
# *SO* if you use numbers in your table names, or column | |
# names, you might get some oddities, but I doubt it. | |
# I mean, how different should the following queries be | |
# considered? | |
# | |
# SELECT car1 FROM autos_10; | |
# SELECT car54 FROM autos_11; | |
# | |
# I don't think so. | |
# | |
$min_time = 25; # Skip queries less than $min_time | |
$max_display = 10; # Truncate display if more than $max_display occurances of a query | |
print "\n Starting... \n"; | |
$query_string = ''; | |
$time = 0; | |
$new_sql = 0; | |
############################################## | |
# Loop Through The Logfile | |
############################################## | |
while (<>) { | |
# Skip Bogus Lines | |
next if ( m|/.*mysqld, Version:.+, started with:| ); | |
next if ( m|Tcp port: \d+ Unix socket: .*mysql.sock| ); | |
next if ( m|Time\s+Id\s+Command\s+Argument| ); | |
if ( /Time:\s+(\d+)\s+Lock_time:\s+(\d+)/ ) { | |
$time = $1; | |
$new_sql = 1; | |
next; | |
} | |
if ( /^\#/ && $query_string ) { | |
if ($time > $min_time) { | |
$query_string =~ s/\d+/XXX/g; | |
$query_string =~ s/([\'\"]).+?([\'\"])/$1XXX$2/g; | |
#$query_string =~ s/\s+/ /g; | |
#$query_string =~ s/\n+/\n/g; | |
push @{$queries{$query_string}}, $time; | |
$query_string = ''; | |
} | |
} else { | |
if ($new_sql) { | |
$query_string = $_; | |
$new_sql = 0; | |
} else { | |
$query_string .= $_; | |
} | |
} | |
} | |
############################################## | |
# Display Output | |
############################################## | |
foreach my $query (sort { @{$queries{$a}} <=> @{$queries{$b}} } keys %queries) { | |
my @seconds = sort { $a <=> $b } @{$queries{$query}}; | |
print "### " . @{$queries{$query}} . " Quer" . ((@{$queries{$query}} > 1)?"ies ":"y ") . "\n"; | |
print "### Taking "; | |
print @seconds > $max_display ? "$seconds[0] to $seconds[-1]" : sec_joiner(\@seconds); | |
print " seconds to complete\n\n"; | |
print "$query\n\n"; | |
} | |
sub sec_joiner { | |
my ($seconds) = @_; | |
$string = join(", ", @{$seconds}); | |
$string =~ s/, (\d+)$/ and $1/; | |
return $string; | |
} | |
exit(0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment