Django如何在不停机的情况下创建索引

本文详细介绍了如何在不停机的情况下,在Django中安全地创建索引,避免因创建索引导致的系统停机。通过理解Django迁移的局限性,学习如何检查和修改迁移,以及使用特定的SQL关键字来并发创建索引,确保在大型表上进行索引优化时保持系统的正常运行。内容包括Django迁移的工作原理、手动创建索引的注意事项、使用RunSQL操作和SeparateDatabaseAndState来实现不停机创建索引的方法。
摘要由CSDN通过智能技术生成

该框架在管理数据库更改方面非常强大和有用,但是该框架提供的灵活性受到了一定的限制。为了理解Django迁移的局限性,你将处理一个众所周知的问题:在不停机的情况下,在Django中创建一个索引。

在本教程中,你将学习:

Django如何以及何时生成新的迁移;

如何检查Django生成的执行迁移的命令;

如何安全地修改迁移以满足你的需求。

本中级教程是为已经熟悉Django迁移(Migration)的读者设计的。

在Django迁移中创建索引的问题

当应用程序存储的数据增长时,通常需要进行的一个常见更改就是添加索引。索引可以用来加快查询速度,并使你的应用程序运行和响应更快。

在大多数数据库中,添加索引时需要对表使用独占锁。在创建索引时,独占锁会防止数据修改(DML)操作,如UPDATE,INSERT,和DELETE。

数据库在执行某些操作时会隐式地获取锁。例如,当用一个户登录到你的应用程序时,Django将更新auth_user表中的last_login字段。要执行更新,数据库首先必须在这个行上获得一个锁。如果该行当前被另一个连接锁定,那么你会得到一个数据库异常。

当需要在迁移期间保持系统可用时,锁定表可能会造成问题。表越大,创建索引所需的时间就越长。创建索引所需的时间越长,系统不可用或对用户无响应的时间就越长。

一些数据库供应商提供了一种创建索引而不锁定表的方法。例如,要在PostgreSQL中创建索引而不锁定表,你可以使用CONCURRENTLY关键字:

fea445c8b6341ce08a141a1e7a15bcd.png

在Oracle中,有一个ONLINE选项允许在创建索引时对表执行DML操作:

be0047b8f96ee72c77a24d6ffd16fbd.png

在生成迁移时,Django不会使用这些特殊的关键字。按原样运行迁移将使数据库获得表上的独占锁,并在创建索引时防止DML操作。

并发创建索引有一些注意事项。提前了解特定于数据库后端的问题是很重要的。例如,PostgreSQL中的一个警告是并发创建索引需要更长的时间,因为它需要进行额外的表扫描。

在本教程中,你将使用Django迁移在一个大型表上创建索引,而不会导致任何停机。

注意:要学习本教程,建议你使用PostgreSQL后端,Django2.x和python3。

也可以使用其他数据库后端。在使用PostgreSQL特有的SQL特性的地方,更改SQL以匹配你的数据库后端。

设置

你将在一个名为app的应用中使用一个虚构的Sale模型。在现实生活中,Sale等模型是数据库中的主要表,它们通常会非常大,并存储大量数据:

9c28fdc8f505f0d6983cd49cac762c4.png

创建表,生成初始迁移并应用它:

a2fd2e843223fa645ea1db361149670.png

一段时间之后,sales表变得非常大,用户开始抱怨速度太慢。在监视数据库时,你注意到许多查询使用sold_at列。为了加快速度,你决定在列上需要一个索引。

要在sold_at上添加索引,你需要对模型进行以下更改:

e7991408841e55a6fc7d01939301c65.png

如果按原样运行这个迁移,那么Django将在表上创建索引,并且它将被锁定,直到索引完成。在非常大的表上创建索引可能需要一段时间,你希望避免停机。

在具有小数据集和很少连接的本地开发环境中,这种迁移可能是瞬间完成的。然而,对于具有许多并发连接的大型数据集,获取锁并创建索引可能需要一

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值