哪个更适合缩放? ORM 的 distinct() 或 python set()
Posted
技术标签:
【中文标题】哪个更适合缩放? ORM 的 distinct() 或 python set()【英文标题】:Which one scales better? ORM's distinct() or python set() 【发布时间】:2012-12-16 12:01:22 【问题描述】:新年快乐!
我有一个模型可以保存数十万条记录。模型如下所示:
class Transaction(models.Model):
user = models.ForeignKey(User)
client = models.ForeignKey(Client)
amount = models.FloatField()
我想知道某个用户正在处理的所有客户。要获取唯一的客户端 ID,我可以单独使用 Django ORM:
Transaction.objects.filter(user=the_user).distinct('client_id').values_list('client_id', flat=True)
或执行以下操作:
set(Transaction.objects.filter(user=the_user).values_list('client_id', flat=True))
两者都会产生相同的结果。但是考虑到大量记录,哪一个会更快?我知道distinct
是一个相对较慢的数据库操作,但它与python 的set()
相比如何?
最后,如果涉及到数据库,我的选择是 mysql 和 PostgreSql 用于生产。对于这个具体的操作,他们两个会有什么区别吗?
【问题讨论】:
我希望您实际上并没有使用浮点数来存储货币金额。 好的,假设我将使用 Decimal,这只是一个简单的示例! :) 我希望.distinct
依赖于 RDBMS 的实现,这可能比 Python 的 set
快得多,以实现唯一性。一个更好的问题是:“我已经使用 timeit 测量了时间,并得到了以下结果:blah, bleh, blih。为什么 blah 比 bleh 快,因为我在 bluh 看到过那个 bloh。”,作为一个模板示例。
您认为 DISTINCT 在数据库上比在 Python 上慢,这让我有点不安。这是一个普遍的信念吗?人们对此有什么理由吗?
我什么都不相信,事实上我不知道,这就是我一开始问的原因!我读到 distinct 是一个相对较慢的操作,我希望人们对此给予启发,我不明白这会如何打扰某人。
【参考方案1】:
我通常使用 orm 函数,它更具可读性,并且在数据库级别上运行,您的 RDBMS 也可以实际计算不同的值,并且您只需一步即可获得结果。
您可以使用 python 集完成相同的操作,但您需要先带上所有数据集,然后应用 set()。所以你必须执行两步操作才能做到这一点。
在您的第一种情况(orm)中,您只有 I/O 开销,而在第二种情况下,您有 I/O 开销 + 一个函数调用,所以我会使用 ORM 的 distinct。
【讨论】:
更重要的是,在第二种情况下,您需要将更多数据从 DB 传输(可能显着)到 Python,这会增加 I/O 开销。当然,好处是 DB 可以减轻一些工作,但希望 DB 的distinct
功能与 Python 的 set
一样有效,或者更有效。
有趣的见解,内存权衡是一个重要因素,因为 RDBMS 无论如何都会加载所有记录。当我有时间时,我会选择不同的,也许会做一个适当的基准测试。谢谢大家!以上是关于哪个更适合缩放? ORM 的 distinct() 或 python set()的主要内容,如果未能解决你的问题,请参考以下文章
MySQL 中的 distinct 和 group by 哪个效率更高?
京东一面:MySQL 中的 distinct 和 group by 哪个效率更高?问倒一大遍。。
京东一面:MySQL 中的 distinct 和 group by 哪个效率更高?问倒一大遍。。