【问题标题】:MySQL query slow because of ORDER BY with Stored Functions由于 ORDER BY 和存储函数,MySQL 查询速度很慢
【发布时间】:2013-11-07 11:17:28
【问题描述】:

当我在以下查询中删除 ORDER BY 时,我的查询从 15 秒变为 0.05 秒:

简化版:

SELECT field1, fiedl2, field 3,  
    FUNC1(1, 2) AS score1,  
    FUNC2(1, 2) AS score2,  
    FUNC3(1, 2) AS score3,  
    FUNC4(1, 2) AS score4  
FROM table  
WHERE field1 = 1  
ORDER BY (score1 * 1 + score2 * 2 + score3 * 2 + score4 * 4) DESC;

我有几个计算子分数的存储函数。除了我必须根据总分排序结果。在 ORDER BY 中,我使用* 2 为子分数添加一些权重以影响总分。

我使用 MySQL 5.6.13

有没有人知道我可以如何制作 ORDER BY,但又不会放慢速度? 是否可以存储 score# 字段并将它们汇总?

谢谢!

【问题讨论】:

  • 好的,我发现了一些东西。 score# 是对存储函数的引用。 ORDER BY 是排序方法,它对这些参考进行了很多比较。所以存储的函数会被执行很多次。有没有办法将存储函数的返回值设置为静态字段?

标签: mysql performance sql-order-by stored-functions


【解决方案1】:

时间上的差异是因为MySql需要创建一个排序后的临时表并用数据填充它。由于使用 order by 时查询运行速度要慢得多,问题可能出在存储临时数据的磁盘中。您没有提到从该查询返回的行数。您也可以尝试手动执行 MySql 可能正在执行的步骤,因此使用主键 (order_by_result int, n int auto_increment) 创建一个临时表并将您的选择结果插入其中:

Insert into t(order_by_result, n, ...)
select (score1 * 1 + score2 * 2 + score3 * 2 + score4 * 4),null,...

并检查 hpw 是否快速运行 - 如果问题出在您的存储上,您也可以通过这种方式检查。

【讨论】:

  • 我正在排序大约 2000 行以及返回前 20 个结果的内容。
  • 所以您是说创建一个临时表,例如:CREATE TEMPORARY TABLE temp_table AS (SELECT field1, .. FROM table) 并对其进行排序?
  • 临时表不是解决方案! :(
  • 能否详细说明您的评论?发生了什么?查询运行得更快吗?您是否尝试过仅填充临时表(主键设置为仅自动递增)?通过这种方式,您可以衡量收集数据阶段所花费的时间。
  • 还有一点需要注意——我是说你需要创建一个临时表 WITH PRIMARY KEY 设置为 order by 子句的值和一个自动增量(自动增量只是为了使值唯一)。这样,当您对此临时表数据运行选择时,其中的数据已经排序。
【解决方案2】:

您可以将total_score 列添加到表中,并定义一个触发器以在添加或更新行时自动更新它。然后索引列,ORDER BY total_score 应该很快。

【讨论】:

  • 是两个表之间的实时算法。我将一张表的值注入到函数中。
  • 在这种情况下,最好考虑将这个函数转换为与另一个表的连接。
  • @RaulLuna 这对 ORDER BY 有什么帮助?
【解决方案3】:

我认为最好的解决方案是预先计算函数的值并将它们存储在数据库中。这样,动态计算函数值的问题将转化为一个非常简单的排序查询。

正如lowleveldesing所说,这种类型的查询会强制mysql在给你任何输出之前计算所有寄存器的乘积(score1 * 1 + score2 * 2 + score3 * 2 + score4 * 4)

【讨论】:

  • 那将是理想的,但不适用于这种情况。我需要实时执行算法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
  • 2017-07-13
  • 1970-01-01
  • 2019-09-12
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多