【问题标题】:How can I optimize this SQL query with ORDER BY RAND()如何使用 ORDER BY RAND() 优化此 SQL 查询
【发布时间】:2012-03-14 09:07:22
【问题描述】:

我正在尝试优化此查询,因为它运行的数据库很大,并且主机说此查询导致服务器负载严重。我已经阅读了一些关于如何替换 ORDER BY RAND() 的其他答案,但我对 SQL 的了解不够,无法将这些答案用于这个特定的查询。任何人都可以帮忙吗? TIA

  SELECT COUNT( p.prod_id ) AS no_prod, s.*
    FROM product p, seller s
   WHERE s.admin_status = '1' 
     AND s.pay_status = '1' 
     AND s.sub_type != '' 
     AND p.seller_id = s.seller_id 
GROUP BY s.seller_id 
  HAVING COUNT( p.prod_id )>5 
ORDER BY RAND() 
   LIMIT 0, 4 

【问题讨论】:

  • 您还阅读了哪些其他问题/答案?请给个链接?
  • 我看不出这个查询是如何工作的——它不是抱怨 SELECT 中的字段从 GROUP BY 中丢失了吗?
  • @Ben 其中大多数涉及 1 个随机行(限制 1),这比检索 4 行更容易。第三个涉及多行但没有得到可靠的答案。
  • @joshuahedlund,公平点,尽管大多数人也像这个一样涉及对表的全面扫描。我会尝试找到一个更好的例子:-)。

标签: mysql sql optimization query-optimization sql-order-by


【解决方案1】:

您最好添加一个包含字段 seller.admin_status、seller.pay_status、seller.sub_type 的非唯一索引。通过索引 WHERE 子句中引用的字段,您将获得最大的收益。

【讨论】:

【解决方案2】:

由于ORDER BY RAND(),您的 SQL 导致严重负载。您可以 google 搜索为什么这是一个问题的原因,并建议修复如何以其他方式实现相同的效果。

在谷歌搜索后我能找到的最佳解释来自 bug report 关于 solaris 系统上的相同问题:

ORDER BY RAND() 使用文件排序,不能像 ORDER BY some_key 那样快。 发生这种情况是因为当您使用 ORDER BY RAND() 时,如果您编写如下查询: SELECT id, rand() FROM t1 ORDER BY RAND(); 这意味着将为表中的每一行创建 rand()。

【讨论】:

    【解决方案3】:

    基于http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/

    SET @MAX_SELLER_ID = SELECT MAX(seller_id) FROM seller;
    
    
    SELECT COUNT( p.prod_id ) AS no_prod,
           s.*
    
    FROM (
      -- preselect a big bunch of random sellers
      SELECT DISTINCT *
      FROM seller
      WHERE seller.id IN (
        FLOOR( RAND() * @MAX_SELLER_ID )
       ,FLOOR( RAND() * @MAX_SELLER_ID )
       ,... -- repeat or generate list of random ids in your app
      )
    ) AS s
    INNER JOIN product p
    
    WHERE s.admin_status = '1' 
      AND s.pay_status = '1' 
      AND s.sub_type != '' 
      AND p.seller_id = s.seller_id 
    
    GROUP BY s.seller_id 
    HAVING COUNT( p.prod_id )>5 
    
    ORDER BY RAND() 
    LIMIT 0, 4;
    

    【讨论】:

    • 很高兴它有帮助。只是不要忘记检查是否已选择所有 5 行。
    猜你喜欢
    • 1970-01-01
    • 2012-06-12
    • 2011-05-13
    • 2016-07-22
    • 2012-12-31
    • 1970-01-01
    • 2022-01-23
    • 2021-08-25
    相关资源
    最近更新 更多