From a3492e14765e3f898efc26913a8e8c4445a837b4 Mon Sep 17 00:00:00 2001
From: Rob Hudson
Date: Mon, 6 Oct 2008 13:53:14 -0700
Subject: Adding query profiling for MySQL. Thanks to Simon Willison for the
suggestion.
There's a big TODO on this one, which is to not display or attempt to execute
the profiling SQL calls if this isn't MySQL and if MySQL isn't >= version
5.0.37. For now it's a nice playground of the profiler if you have MySQL
v5.0.37 or higher.
---
.../templates/debug_toolbar/panels/sql.html | 1 +
.../debug_toolbar/panels/sql_profile.html | 26 ++++++++++++++++
debug_toolbar/urls.py | 1 +
debug_toolbar/views.py | 35 ++++++++++++++++++++++
4 files changed, 63 insertions(+)
create mode 100644 debug_toolbar/templates/debug_toolbar/panels/sql_profile.html
(limited to 'debug_toolbar')
diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html
index 2abb68f..d35d83e 100644
--- a/debug_toolbar/templates/debug_toolbar/panels/sql.html
+++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html
@@ -15,6 +15,7 @@
{% if query.params %}
SELECT
EXPLAIN
+ PROFILE
{% endif %}
{{ query.sql|safe }} |
diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql_profile.html b/debug_toolbar/templates/debug_toolbar/panels/sql_profile.html
new file mode 100644
index 0000000..c1d04ce
--- /dev/null
+++ b/debug_toolbar/templates/debug_toolbar/panels/sql_profile.html
@@ -0,0 +1,26 @@
+« Back
+SQL Profiled
+
+ - Executed SQL
+ {{ sql|safe }}
+ - Time
+ - {{ time }} ms
+
+
+
+
+ {% for h in headers %}
+ | {{ h|upper }} |
+ {% endfor %}
+
+
+
+ {% for row in result %}
+
+ {% for column in row %}
+ | {{ column|escape }} |
+ {% endfor %}
+
+ {% endfor %}
+
+
diff --git a/debug_toolbar/urls.py b/debug_toolbar/urls.py
index 437d36b..53a426b 100644
--- a/debug_toolbar/urls.py
+++ b/debug_toolbar/urls.py
@@ -11,4 +11,5 @@ urlpatterns = patterns('',
url(r'^__debug__/m/(.*)$', 'debug_toolbar.views.debug_media'),
url(r'^__debug__/sql_select/$', 'debug_toolbar.views.sql_select', name='sql_select'),
url(r'^__debug__/sql_explain/$', 'debug_toolbar.views.sql_explain', name='sql_explain'),
+ url(r'^__debug__/sql_profile/$', 'debug_toolbar.views.sql_profile', name='sql_profile'),
)
diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py
index 4b666e1..8af879f 100644
--- a/debug_toolbar/views.py
+++ b/debug_toolbar/views.py
@@ -81,3 +81,38 @@ def sql_explain(request):
'headers': headers,
}
return render_to_response('debug_toolbar/panels/sql_explain.html', context)
+
+def sql_profile(request):
+ """
+ Returns the output of running the SQL and getting the profiling statistics.
+
+ Expected GET variables:
+ sql: urlencoded sql with positional arguments
+ params: JSON encoded parameter values
+ time: time for SQL to execute passed in from toolbar just for redisplay
+ hash: the hash of (secret + sql + params) for tamper checking
+ """
+ from debug_toolbar.panels.sql import reformat_sql
+ sql = request.GET.get('sql', '')
+ params = request.GET.get('params', '')
+ hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest()
+ if hash != request.GET.get('hash', ''):
+ return HttpResponse('Tamper alert
') # SQL Tampering alert
+ if sql.lower().startswith('select'):
+ params = simplejson.loads(params)
+ cursor = connection.cursor()
+ cursor.execute("SET PROFILING=1") # Enable profiling
+ cursor.execute(sql, params) # Execute SELECT
+ cursor.execute("SET PROFILING=0") # Disable profiling
+ # The Query ID should always be 1 here but I'll subselect to get the last one just in case...
+ cursor.execute("SELECT * FROM information_schema.profiling WHERE query_id=(SELECT query_id FROM information_schema.profiling ORDER BY query_id DESC LIMIT 1)")
+ headers = [d[0] for d in cursor.description]
+ result = cursor.fetchall()
+ cursor.close()
+ context = {
+ 'result': result,
+ 'sql': reformat_sql(cursor.db.ops.last_executed_query(cursor, sql, params)),
+ 'time': request.GET.get('time', 0.0),
+ 'headers': headers,
+ }
+ return render_to_response('debug_toolbar/panels/sql_explain.html', context)
--
cgit v1.2.3