好久沒有寫博客了,記錄一些東西吧git
寫django程序時因爲直接和django model交互,對sql的操做不是那麼直觀。因此很容易形成一些sql查詢問題。github
如常見的sql分頁位置不正確致使查詢整個表,屢次queryset沒有利用緩存致使屢次sql重複查詢等。以前一直用打印的方式查詢,感受仍是不夠方便。sql
因而有了下面的sql中間件,在本地開發時每次輸出sql的一些簡單分析信息提供參考django
class DjangoSqlInspectMiddleware(object): def process_request(self, request): self.start_end_chars_dict = {'start_chars': '<' * 20, 'end_chars': '>' * 20} self.start = time.time() logger.info(os.linesep * 4) logger.info('%(start_chars)s sql analyse start %(end_chars)s' % self.start_end_chars_dict) def process_response(self, request, response): sqltime_list = connection.queries pprint.pprint(sqltime_list) duplicate_sqltime_dict = defaultdict(int) sql_total_time = 0 max_sqltime, min_sqltime = (None,) * 2 for st in sqltime_list: sql = st['sql'] sql_total_time += float(st['time']) duplicate_sqltime_dict[sql] = duplicate_sqltime_dict[sql] + 1 if not max_sqltime or not min_sqltime: max_sqltime = min_sqltime = st else: t = st['time'] if t > max_sqltime['time']: max_sqltime = st if t < min_sqltime['time']: min_sqltime = st self.end = time.time() consume_time = self.end - self.start logger.info('[SQL] %s queries, %s SQL time, %s total request time' % (len(duplicate_sqltime_dict), sql_total_time, consume_time)) logger.info('[MAX TIME]: %s seconds' % (max_sqltime['time'], )) logger.info('[MAX TIME SQL]:%s %s' % (os.linesep, max_sqltime['sql'])) logger.info('[MIN TIME]: %s seconds' % min_sqltime['time']) logger.info('[MIN TIME SQL]:%s %s' % (os.linesep, min_sqltime['sql'])) logger.info('[CHECK DUPLICATE]:') for k, v in duplicate_sqltime_dict.iteritems(): if v > 1: logger.info('(%s)' % v + k) logger.info('---------------------------------------------') logger.info('%(start_chars)s sql analyse end %(end_chars)s' % self.start_end_chars_dict) logger.info(os.linesep * 2) return response
主要程序如上, 若是感興趣的同窗能夠在github上一塊兒完善或者有更好的方式給予建議哈緩存