【发布时间】: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