欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > Django ORM 数据库管理 提高查询、更新性能的技巧和编程习惯:

Django ORM 数据库管理 提高查询、更新性能的技巧和编程习惯:

2025/2/25 13:38:02 来源:https://blog.csdn.net/bigcarp/article/details/143322665  浏览:    关键词:Django ORM 数据库管理 提高查询、更新性能的技巧和编程习惯:

在Django中使用ORM进行数据库管理时,以下是一些提高数据查询、更新和插入效率的技巧和编程习惯:

1. 索引优化 - 效果最显而易见

  • 为常用的查询字段(如外键、唯一字段等)添加数据库索引,可以显著提高查询速度。
class Book(models.Model):title = models.CharField(max_length=255, db_index=True)

以下是一个很常见的例子(并非极端条件才发生):在配置低的服务器上,表格TableA 的记录数10w,字符串字段K无索引,一个简单查询耗时10秒,一个插入耗时50毫秒。如果K建立索引,查询耗时降可到毫秒级别,插入耗时增加也只是毫秒级别。总体上,索引带来的查询性能提升(10秒级)会远远大于插入性能的下降(毫秒级)。

2. 使用only()defer()

  • only():仅加载指定字段,用于降低内存占用和传输开销。
  • defer():延迟加载某些字段,适用于大字段,如Blob或TextField。

> 如果表中字段类型较小(例如都是int类型),而且返回的数据条数很少,其实可以忽略不使用.only()带来的性能差异。

> 如果表中的字段是大数据类型(如长字符串或BLOB),应使用.only()来优化查询

# Example of only()
users = User.objects.only('id', 'username').all()# Example of defer()
books = Book.objects.defer('description').all()

 3. 合理使用批量操作

  • 批量插入:使用bulk_create(),可以一次性插入多条数据,减少数据库的连接和提交次数。
  • 批量更新:使用bulk_update(),高效更新多条记录。
  • 批量删除:使用delete()而不是逐条删除。
# Example of bulk_create()
Book.objects.bulk_create([Book(title='Book 1'),Book(title='Book 2'),Book(title='Book 3')
])# Example of bulk_update()
books = Book.objects.filter(published=False)
for book in books:book.published = True
Book.objects.bulk_update(books, ['published'])

4. 分页查询

  • 对大量数据进行分页处理,避免一次性加载过多数据,占用内存资源。使用Paginator类或iterator()方法来进行分页和流式处理。
    from django.core.paginator import Paginatorbooks = Book.objects.all()
    paginator = Paginator(books, 10)  # 每页10条数据
    page_1_books = paginator.get_page(1)
    

5. 使用事务(Transactions)

  • 对于多条相关操作(如插入、更新、删除),使用事务来保证数据一致性和操作的原子性,同时避免多次提交的开销。
    from django.db import transactionwith transaction.atomic():author = Author.objects.create(name='Author')book = Book.objects.create(title='Book', author=author)
    

 6. 使用原生SQL和原生查询(Raw Queries)

  • 对于极其复杂或高性能要求的查询,使用Django的raw()方法执行原生SQL语句,或者使用RawSQL来插入自定义SQL。
from django.db import connectionbooks = Book.objects.raw('SELECT * FROM book WHERE title = %s', ['Django'])

7. get()filter()的使用 -- 效率其实差不多

如果可以确保匹配结果有且只有一个(即无需处理异常),get()通常略微更高效,但几乎可以忽略不计。对于非预期结果的处理filter().first()通常更轻松,由于不需要try,代码更简洁,可读性更强。

# Efficient way to get the first matched record
book = Book.objects.filter(title='Django').first()

8. 使用Q对象和F表达式

  • Q对象:用于组合复杂的查询条件。
  • F表达式:允许在查询或更新时直接引用字段的值,避免多次读取数据库,提高更新操作效率。
    from django.db.models import Q, F# Example of Q object
    books = Book.objects.filter(Q(title__icontains='Django') | Q(author__name='John'))# Example of F expression
    Book.objects.filter(id=1).update(page_count=F('page_count') + 1)
    

    9. 缓存查询结果

  • 对于频繁使用但不经常变动的数据,可以使用缓存来减少数据库访问次数。Django内置的缓存框架支持多种缓存机制,如内存、文件、数据库等。
from django.core.cache import cachebooks = cache.get('all_books')
if not books:books = Book.objects.all()cache.set('all_books', books, 60*15)  # 缓存15分钟

10. 使用select_related()prefetch_related()

  • select_related():用于减少多表查询的数量,适合在一对一或外键关系中使用。它在单个SQL查询中加入JOIN操作,加载相关表的数据。
  • prefetch_related():适合多对多或反向外键关系,用于预取相关对象并减少SQL查询数量。
  • 巧妙地组合使用这两个方法,减少N+1查询问题。
# Example of select_related()
books = Book.objects.select_related('author').all()# Example of prefetch_related()
authors = Author.objects.prefetch_related('books').all()

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词