【问题标题】:Why does the query take a long time in mysql even with a LIMIT clause?为什么即使使用 LIMIT 子句,在 mysql 中查询也需要很长时间?
【发布时间】:2012-11-28 23:42:50
【问题描述】:

假设我有一个包含 100 多列和 100 万行的 Order 表。它在 OrderID 和 FK 约束 StoreID 上有一个 PK --> Store.StoreID。

1) select * from 'Order' order by OrderID desc limit 10;

以上需要几毫秒。

2) select * from 'Order' o join 'Store' s on s.StoreID = o.StoreID order by OrderID desc limit 10;

不知何故,这可能需要几秒钟。我添加的内部连接越多,速度就越慢。

3)select OrderID, column1 from 'Order' o join 'Store' s on s.StoreID = o.StoreID order by OrderID desc limit 10;

这似乎通过限制我们选择的列来加快执行速度。

这里有几点我不明白,如果有更了解mysql(或一般的rmdb查询执行)的人能启发我,我将不胜感激。

查询 1 很快,因为它只是 PK 的反向查找,而 DB 只需要返回它遇到的前 10 行。

我不明白为什么 Query 2 应该永远存在。操作不应该一样吗?即通过 PK 获取前 10 行,然后 然后 与其他表连接。由于存在 FK 约束,因此可以保证满足该关系。所以 DB 不需要加入比必要更多的行然后修剪结果,对吗?除非,FK 约束允许空 FK?在这种情况下,我猜左连接会比内连接快得多?

最后,我猜查询 3 更快,因为在那些不必要的连接中使用了更少的列?但是为什么在加入时查询执行需要其他列呢?不应该先使用 PK 加入,然后只获取 10 行的列吗?

谢谢!

【问题讨论】:

  • 如果你有一个有 100 列的表格,那么表格的设计就有很大的问题。根据经验,RDBMS 擅长长薄表,只要您可以应用合理的 btree 索引。
  • 虽然指出糟糕的设计很容易,但人们不会简单地从头开始编写所有内容或一有机会就重新设计/重新编写。 =)
  • Xerion:实际上要指出一个糟糕的设计并不容易——如果有,那么糟糕的设计就会更少。它实际上需要了解关系数据库背后的基本概念,以及一些有效设计模式的经验。然而,我不需要任何人说,当你规定你有一个包含 100 多列的表时,这种设计是完全错误的。我知道它可能不是你的设计,你可能无法改变它,但你也被画在一个角落里,本来应该简单且高性能的东西都不是。

标签: mysql


【解决方案1】:

我的理解是mysql引擎在任何join发生后应用limit

来自http://dev.mysql.com/doc/refman/5.0/en/select.htmlThe HAVING clause is applied nearly last, just before items are sent to the client, with no optimization. (LIMIT is applied after HAVING.)

编辑:您可以尝试使用此查询来利用 PK 速度。

select * from (select * from 'Order' order by OrderID desc limit 10) o join 'Store' s on s.StoreID = o.StoreID;

【讨论】:

  • 除了答案中的可读性/格式之外,您的最终查询正是我所建议的......
【解决方案2】:

您的所有示例都要求对现有表进行表扫描,因此它们的性能都不会超过 mysql 可以缓存数据或结果的程度。您的某些查询具有 order by 或 join 条件,这可以纯粹利用索引来提高连接过程的效率,但是,这仍然与拥有一组将触发使用索引的条件不同。

限制不是标准——一旦确定了结果集,就可以将其视为过滤。准备好结果集后,您可以在客户端节省时间,但不会在服务器上节省时间。

确实,获得您正在寻找的答案的唯一方法是熟悉: 解释扩展 your_sql_statement

EXPLAIN 的输出将显示 mysql 正在查看多少行,以及是否正在使用任何索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 2017-02-18
    • 2016-02-18
    • 1970-01-01
    • 2018-12-07
    • 1970-01-01
    相关资源
    最近更新 更多