mysql - 在 MySQL 中通过复杂表达式获取 N 行顺序的有效方法

标签 mysql performance sorting sql-order-by limit

我有一个表 line_item { id: int, price: decimal, quantity: int, [other:...] }。这张 table 很大,大约。 2800 万行。现在我想获取前 1000 行 order by f(price, quantity, [other...])f 是一个任意函数。最好的方法是什么?

我想到了 2 个解决方案:

  1. 使用order bylimit。这种方式可能会很慢,因为我认为 MySQL 会为每一行计算 f 的结果,然后对它们进行排序。
  2. 创建新列来存储函数 f 的结果。这种方式不利于可扩展性,因为我可能想在不同的上下文中使用多个函数 f(f1f2...)。

我真的希望有比他们更好的第三种解决方案。

最佳答案

(抱歉,这是一个否定的答案,但这就是生活。)

如果您接受“最佳解决方案”的速度仅为您所经历的速度的两倍,那么请接受@Zsuzsa 的。

我在这里告诉你,如果不对 f(...) 做一些事情,它就无法优化。原因如下:

优化器看不到 WHERE 子句,但看到带有表达式的 ORDER BY。因此,它意识到评估查询的唯一方法是进行“表扫描”(即读取所有行),评估每一行的函数,将结果保存在 tmp 中表(2800 万行),对该 tmp 表进行排序,并交付 1000 行。

能否将该函数的任何复制到 WHERE 子句中以过滤掉某些行?如果是这样,tmp 表可能会更小。或者,如果幸运的话,也许可以设计一些 INDEX,这样它就不必进行全表扫描。

您要修改所有行吗?还是这种“只写”表?也就是说,一行一旦写入就永远不会改变吗?在此基础上,可以为所有“旧”行预先计算 f() 吗?如果是这样,将它存储在某个地方并添加一个索引——噗!即时结果。

f() 的公共(public)部分是对某个日期范围的测试吗? (大表通常有某种日期。大表上的查询通常会询问“最近”的项目。)如果是这样,是否可以将其从 f() 中提取出来。然后我们可以考虑按日期对表进行分区。这样,即使在 f 中没有其他东西可以优化,“分区修剪”也可以限制要处理的行数。

请显示 CREATE TABLE 并讨论这里的一些想法是否可行。

关于mysql - 在 MySQL 中通过复杂表达式获取 N 行顺序的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28682307/

相关文章:

java - 对具有许多相等值的数组进行排序java

MongoDB:对 UTF-8 字符串进行排序

php - 如果在另一行中指定,则MySQL选择行

php - 使用包含连接时如何从 MySql 数据库中获取?

mysql - mysql过程中用户定义的变量增量

mysql - 定期将数据加载到表中的最佳方法是什么

android - 在 Activity 布局的 Root View 上使用 Android <merge> XML 元素

mysql - 在mysql中获取与日期对应的季度

mysql - 优化大量更新查询

android - 如何在 flutter 中按字母顺序对外部存储中的歌曲列表进行排序