之前我们有介绍过使用django-auto-prefetching来解决Django REST 框架和 n+1 问题。是否有任何工具、插件和技术可用于帮助我们识别 Django 应用程序上的 n+1 个查询?今天我们将介绍二种方式,其中django-debug-toolbar或许大家都很熟悉。
django-debug-toolbar
Django 的调试工具栏。可显示当前请求和响应有关的各种调试信息,包括耗时、SQL、配置、性能等信息。
nplusone
nplusone是一个 ORM 分析工具,用于帮助诊断和改进由不适当的延迟加载导致的性能不佳。nplusone使用 Django 或 SQLAlchemy 监视应用程序,并在可能产生昂贵的惰性加载时发送通知。它可以识别问题背后的违规关系属性和特定代码行,并为更好的性能提出修复建议。
安装
pip install -U nplusone
注意
- 1、nplusone 支持 Python >= 2.7 或 >= 3.3。
- 2、nplusone只能用于开发,不能部署到生产环境。
- 3、nplusone支持 Django >= 1.8。
Django用法
添加nplusone到INSTALLED_APPS:
INSTALLED_APPS = (
...
'nplusone.ext.django',
)
添加中间件NPlusOneMiddleware:
MIDDLEWARE = (
'nplusone.ext.django.NPlusOneMiddleware',
...
)
可选配置日志记录设置:
NPLUSONE_LOGGER = logging.getLogger('nplusone')
NPLUSONE_LOG_LEVEL = logging.WARN
配置日志处理程序:
LOGGING = {
'version': 1,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'nplusone': {
'handlers': ['console'],
'level': 'WARN',
},
},
}
日志
当您的应用程序延迟加载数据时,nplusone将发出日志消息:
Potential n+1 query detected on `<model>.<field>`
orders = OutboundOrder.objects.all()
for order in orders:
owner_name = order.owner.name #未使用.select_related('owner')或者prefetch_related
在这种情况下,请考虑使用select_related或prefetch_related。
当您的应用急切加载相关数据而不访问它时,nplusone将记录警告:
Potential unnecessary eager load detected on `<model>.<field>`
orders = OutboundOrder.objects.all().select_related('owner')
for order in orders:
print(order) # 使用了.select_related('owner') 未对owner数据进行访问