论坛首页 编程语言技术论坛

django debug toolbar自定义面板分析重复的SQL语句

浏览 2518 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-04-29  

django debug toolbar可以说是Django最好的app之一了,在实际开发中用来查看变量,分析性能等各方面都有不错的效果。

实际上 django debug toolbar 有两个主要版本:

一个是原版:

http://github.com/robhudson/django-debug-toolbar/tree/master

 

还有一个不太为人知的分支版本:

http://github.com/dcramer/django-debug-toolbar/tree/master

 

这两个版本的区别比较小,主要有以下几点:

1、分支版本的界面比原版稍微好看一点,因为使用了一些圆角效果和更多的js处理。

2、分支版本可以分析重复的SQL语句,原版没这个功能。

3、分支版本还有一个功能稍微强大点的性能分析面板,原版只有只有查看页面总生成时间的功能。

4、分支版本由于多了一些功能,尤其是性能分析面板开启后,严重影响页面打开速度。

5、分支版本几乎不太更新了,原版还是几乎每个月都有点小的更新。

 

一开始我更倾向于使用分支版本,因为重复SQL分析实在是个好东西,在使用ORM时对性能优化有非常大的帮助。

但是分支版本的执行速度实在不敢恭维。

 

后来通过比较两个版本的SQL面板代码,自己写了一个针对原版的专门分析重复SQL的面板。实际上代码也不是很复杂,基本就是从connection对象取出raw_sql,然后存入dict一个个分析是否重复。

代码如下:

# -*- coding: utf-8 -*-
from django.db import connection
from django.template.loader import Template, Context
from debug_toolbar.panels.sql import SQLDebugPanel, reformat_sql

template_string = '''
<h3>{{unique_count}} Unique Queries</h3>
<table>
    <thead>
        <tr>
            <th>Time&nbsp;(ms)</th>
            <th>Count</th>
            <th>Params</th>
            <th>Query</th>
        </tr>
    </thead>
    <tbody>
        {% for query in query_groups %}
            <tr class="{% cycle 'djDebugOdd' 'djDebugEven' %}">
                <td>{{ query.1|floatformat:"2" }}</td>
                <td>
                    {{ query.2}}
                </td>
                <td>
                    {% for p in query.3 %}
                        {{ p }}<br />
                    {% endfor %}
                </td>
                <td class="syntax">{{ query.0|safe }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

'''
class SQLUniqueDebugPanel(SQLDebugPanel):
    
    name = 'SQL Unique Queries'
    has_content = True
    
    def __init__(self):
        self._offset = len(connection.queries)
        self._sql_time = 0
        
        
    def url(self):
        return ''
    
    def title(self):
        sql_queries = connection.queries[self._offset:]
        queries = [(q['time'], q['raw_sql'], q['params']) for q in sql_queries]
        query_groups = {}
        for item in queries:
            time, raw_sql, params = item[0], item[1], item[2]
            group = query_groups.get(raw_sql, [0, 0, []])
            group[2].append(params)
            query_groups[raw_sql] = (group[0]+time, group[1]+1, group[2])

        query_groups = sorted([[k, v[0], v[1], v[2]] for k, v in query_groups.iteritems()], key=lambda x: x[1])[::-1]
        for query_group in query_groups:
            query_group[0] = reformat_sql(query_group[0])
        self.query_groups = query_groups
        self.unique_count = len(query_groups)
        return '%s Unique Queries' % self.unique_count

    def content(self):
        c = Context({
            'query_groups': self.query_groups,
            'unique_count': self.unique_count
        })
        t = Template(template_string, name='SQLUniqueDebugPanel template')
        
        return t.render(c)

 

 

如何使用

 

首先就是要让 sys.path 能找到原版的pythonpath,因为以上代码的SQLUniqueDebugPanel部分使用了原版的代码。

第二你可以把以上代码拷贝后放到任意pythonpath可以找到的地方。然后像原版的面板设置一样加上这个面板的路径即可。

比如:

DEBUG_TOOLBAR_PANELS = (
#    'debug_toolbar.panels.version.VersionDebugPanel',
    'debug_toolbar.panels.timer.TimerDebugPanel',
    'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
    'debug_toolbar.panels.headers.HeaderDebugPanel',
    'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
    'debug_toolbar.panels.template.TemplateDebugPanel',
    'debug_toolbar.panels.sql.SQLDebugPanel',
    'debug_panels.sql_unique.SQLUniqueDebugPanel',
    'debug_toolbar.panels.logger.LoggingPanel',
    'debug_toolbar.panels.cache.CacheDebugPanel',
)

上面是将这个面板放在原版的SQL面板旁边方便使用:

最后你就可以看到toolbar上多出了一个面板,点击该面板就可以看到分析情况了。

包括每个重复的总执行时间,次数,以及每次重复执行使用的不同参数和原始SQL语句。

 

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics