`
lizhuang
  • 浏览: 902768 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

数据库n+1问题解决方案

 
阅读更多
数据库N+1查询是个常见的问题,简单描述场景如下

基本场景
class Category(models.Model):
    name = models.CharField(max_length=30)

class Article(models.Model):
    title = models.CharField(max_length=30)
    body = models.TextField()
    category = models.ForeignKey(Category)
    time    = models.DateTimeField()

    #----列表页模板{% for a in Article.objects.all %}
        {{ a.title }}
        {{ a.category.name }}
   {% endfor %}
在生成列表页面时,首先执行一次

select * from article limited 0,N

然后逐条获取category.name,又需要执行N次

select name from category where id = category_id

所以N+1问题其实应该叫做1+N 问题,这只是一个数据库设计模式的问题.但是会对数据库带来很大的压力,一个简单的列表页可能会有几百次数据库查询

N+1问题并不是ORM独有,只是使用orm的时候,数据库表中的行变成一个对象,于是很自然的就容易使用上面的方法来进行查询不使用orm进行编程的情况,一般直接用子查询或者inner join

select a.*,c.name from article a,category b where a.category_id = b.id

子查询或者inner join对数据库来说,也是很费资源的操作,因为需要锁表,高并发的情况下很容易锁死

要解决1+N问题一般有3种方法

数据库反范式设计,说直白点,就是把表合并,设计成冗余表,这可能会带来两个问题

表中存在大量的重复数据项
表中出现大量的空项,整个表格变成一个稀疏矩阵(sparse matrix)
所以,这种方案显然存储效率不高,但是如果针对这两种情况进行优化,也算是是一种不错的解决办法, MongoDB就是这样干的

加缓存 把整个列表页加上缓存. 这样 无论是继续执行1+N次查询,还是用inner join 1次查询搞定,都可以.

这种方法的缺点是

更新缓存 需要成本,增加了代码复杂度
某些场景要求数据实时性,无法使用缓存
把N+1次查询变成2次查询

简单说 先执行 select *,category_id from article limited 0,N

然后遍历结果列表,取出所有的category_id,去掉重复项

再执行一次 select name from category where id in (category id list)

性能优化
把子查询/join查询 分成两次,是 高并发网站数据库调优中非常有效的常见做法,虽然会花费更多的cpu时间,但是避免了系统的死锁,提高了并发响应能力

数据库本身处理不了高并发,因为我们只能保证单个数据项的操作是原子的,而数据库的查询是以 列表为基本单元,这是个天然矛盾,无解

数据库设计范式不在web framework能力范围内,所以django的ORM 只支持后面两种做法

Article.ojbects.select_related() 这就是inner join
Article.objects.prefetch_related('category') 这是2次查询
本文地址: http://lutaf.com/156.htm 鲁塔弗原创文章,欢迎转载,请附带原文链接
分享到:
评论

相关推荐

    hibernate N+1问题解决办法

    本文将详细探讨Hibernate中的N+1问题,并提供有效的解决方案。 **N+1查询问题的由来** 当我们在Hibernate中使用懒加载或集合查询时,如果在一次循环中对每个实体逐一触发关联对象的加载,就会产生N+1次数据库查询...

    ibatis解决多对一n+1问题(更新上传例子(mybatis)代码)

    "ibatis解决多对一n+1问题"这个主题聚焦于MyBatis框架中如何高效地处理多对一关联查询,避免出现性能瓶颈的“n+1”问题。这个问题通常发生在查询一对多关系时,如果不对查询进行优化,会导致大量的额外数据库访问,...

    Mysql解决数据库N+1查询问题

    在数据库管理中,N+1查询问题是一种常见的性能瓶颈,特别是在使用ORM(对象关系映射)框架如Hibernate或MyBatis时。这个问题出现在当我们需要获取一个对象及其关联对象时,通常会先执行一次主查询获取主对象,然后对...

    ibatis N+1问题

    在IT行业中,数据库查询优化是提升系统性能的关键环节之一,而"Ibatis N+1问题"是使用MyBatis框架时常见的性能瓶颈。这个问题通常出现在一对多或者多对多的关联查询中,导致了大量的数据库交互,严重影响了应用的...

    ibatis n+1选择问题 的几种解决方案

    综上所述,解决iBATIS中的N+1选择问题需要结合业务场景和数据库设计,选择合适的策略进行优化。通过合理地使用批处理、联合查询、预加载、缓存等方法,我们可以显著提升系统的性能和响应速度。在实践中,还需要注意...

    hibernate的n+1问题.docx

    《理解Hibernate中的N+1问题及其解决方案》 在Java开发中,Hibernate作为一款流行的ORM(对象关系映射)框架,极大地简化了数据库操作。然而,使用不当可能会导致性能瓶颈,其中最典型的就是“N+1次SELECT查询问题...

    How to solve the hibernate N+1 problem?

    标题 "如何解决Hibernate的N+1问题" 涉及的是一个常见的数据库查询优化问题,主要出现在使用Hibernate等ORM框架时。N+1问题是指在进行一对多或多对多关联查询时,原本期望通过一次SQL查询获取所有数据,但实际执行了...

    WIFI+Portal认证解决方案_高可靠性.docx

    为了确保高可用性,通常采用N+1或N+X的部署策略。 3. **冗余设备**:采用第三方设备如防火墙和负载均衡器,并设置为热备模式,以保证即使某一设备故障,其他设备也能立即接管,维持系统运行。 4. **数据库选型与...

    创意信息N+项目ppt

    N+项目针对这些挑战提出了解决方案。N+是一个面向行业大数据的智能业务快速生成与管理平台,其核心特性包括: 1. **整体架构设计**:N+采用模块化设计,包括可视化组件开发与调试、集成开发环境N+ Studio、组件管理...

    在VMWare中配置SQL Server 2005 N+1群集

    在SQL Server 2005中,N+1群集是指一种高可用性解决方案,其中“N”代表一个基本的群集节点数量,而“+1”则表示备用节点,当任何工作节点出现故障时,该备用节点能够接管服务,确保系统的连续运行。这种架构旨在...

    graphql-n-plus-one-example:GraphQL中的N + 1问题的示例

    现在,让我们深入探讨GraphQL中的N+1问题及其解决方案。 首先,我们要理解什么是N+1查询。想象一下,你有一个用户列表,每个用户都有一个关联的地址。在查询这些用户时,如果每次获取一个用户后再单独查询其地址,...

    汇编程序:功能性,类型安全和无状态的Java API,用于解决多数据库和微服务聚合中的N + 1查询问题

    更具体地说,它被设计为一种非常轻量级的解决方案,用于解决聚合数据时的N + 1查询问题,这些问题不仅来自数据库调用(例如Spring Data JPA,Hibernate),而且来自任意数据源(关系数据库,NoSQL,REST,本地方法...

    在 VMWare 中配置 SQL Server 2005 N + 1 群集

    在VMware环境中配置SQL Server 2005 N+1群集是一项复杂而重要的任务,它涉及到虚拟化技术、数据库集群以及高可用性解决方案。在这个过程中,我们需要理解以下几个关键知识点: 1. **虚拟化基础**:VMware是一个领先...

    djangoORM如何处理N+1查询.docx

    然而,如同其他ORM工具,Django ORM也可能导致一种性能问题,通常被称为“N+1查询”问题,或者更准确地说,“1+N查询问题”。 1+N查询问题指的是在进行数据检索时,对于一个主对象,我们需要额外单独查询多个关联...

    Hibernate 1+N问题详解

    - 但同时也可能导致“N+1”问题,即除了主表查询外,还需要额外的查询来加载每个关联的子记录,这在子记录较多时可能会导致性能下降。 **2. FetchType.LAZY:** - `LAZY`加载方式则是延迟加载,即只有当真正访问到...

    python3.7+安装pyspider报错解决方案.docx

    #### 遇到的问题与解决方案 ##### 1. 格式错误 - `SyntaxError: invalid syntax` **问题描述**: 当尝试使用 Python 3.7 安装 PySpider 时,可能会遇到如下的语法错误: ``` async=True,get_object=False,no_input=...

    Hibernate教程24_Hibernate的1+N问题

    在IT行业中,Hibernate是一个非常重要的Java持久化框架,它...在提供的源码`s2sh_relation23_1+N`中,可能包含了示例代码,用于演示如何处理这种情况,通过学习和实践这些代码,可以更好地理解这个问题及其解决方案。

    两台SQL+Server数据同步解决方案

    "两台SQL Server数据同步解决方案" 在本文中,我们将讨论两台SQL Server数据同步解决方案的概念和实现步骤。数据同步是将一组数据从一个数据源拷贝到多个数据源的技术,是将一份数据发布到多个存储站点上的有效方式...

Global site tag (gtag.js) - Google Analytics