【问题标题】:Which has optimal performance for generating a randomized list: `random.shuffle(ids)` or `.order_by("?")`?哪个具有生成随机列表的最佳性能:`random.shuffle(ids)` 或 `.order_by("?")`?
【发布时间】:2019-12-20 07:23:21
【问题描述】:

我需要生成一个包含 50 个项目的随机列表,以发送到前端以显示登录页面。着陆页已经加载得太慢了,所以任何优化都会很棒!

鉴于预先存在的性能问题和该表的大尺寸,我想知道哪种实现是更好的做法,或者差异是否可以忽略不计:

选项 A:

unit_ids = list(units.values_list('id', flat=True).distinct())
random.shuffle(unit_ids)
unit_ids = unit_ids[:50]

选项 B:

list(units.values_list('id', flat=True).order_by("?")[:50])

我担心的是,根据 django 文档,order_by('?')“可能既昂贵又缓慢” https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.order_by

我们正在使用 MySQL 数据库。我尝试搜索有关实施的更多信息,但我没有看到比文档中的内容更具体的内容。救命!

【问题讨论】:

  • 视情况而定。首先......表中有多少行?有TEXT 列吗?你会展示多少? (显然是“50”)您在客户端中有 ID 列表吗?如果没有,获得这样的成本是多少?

标签: python mysql django optimization


【解决方案1】:

在大多数情况下,选项 B 应该更快,因为数据库引擎通常比 python 中的代码更快。

在选项 A 中,您正在检索一些我猜应该是所有 id 的 id,然后您在 python 上将它们改组。根据您的说法,该表很大,因此在 python 中执行此操作不是一个好主意。此外,您只能获取 id,这意味着如果您需要实际数据,则必须进行另一个查询。

有了所有的解释,您仍然应该尝试两者,看看哪个更快,因为它们都依赖于不同的变量。只需对它们进行计时,看看哪一个对您来说效果更快,然后继续使用。

【讨论】:

    【解决方案2】:

    权衡:

    • 向客户端推送大量数据(TEXT 列;所有行等)
    • 表是否大到随机取 N 行可能会撞到磁盘 N 次。

    我的第一选择很简单:

    SELECT * FROM t ORDER BY RAND() LIMIT 50;
    

    我的第二个选择是使用“延迟加载”(与您的 random.shuffle 不同,但更好,因为它不需要第二次往返):

    SELECT t.*
        FROM ( SELECT id FROM t ORDER BY RAND() LIMIT 50 ) AS r
        JOIN t  USING(id)
    

    如果这还不够“快”,那么首先找出子查询是减速还是外部查询。

    如果内部查询有问题,那么看http://mysql.rjweb.org/doc.php/random

    如果外部查询是问题所在,那你就完蛋了。它已经是最优的(假设PRIMARY KEY(id))。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      • 2017-03-23
      • 1970-01-01
      • 2016-05-23
      • 1970-01-01
      • 2015-12-22
      相关资源
      最近更新 更多