【问题标题】:Avoid joins or not?是否避免加入?
【发布时间】:2016-10-13 11:15:05
【问题描述】:

假设您有一个包含 5000 万个帖子的表 POSTS。该表有:

ID, POST, CATEGORY_ID
1, "Hello world", 2

然后你有一个 CATEGORIES 表:

ID, CATEGORY_NAME
1, "Football"
2, "Baseball"

在网站上,您在 ORDER DESC 中列出这些帖子,使用连接显示帖子和类别名称。

[Baseball]
Hello World!

我正在考虑将 CATEGORY_NAME 列添加到 POSTS 表中(当有人创建新帖子时),以避免每次访问时都必须进行该 JOIN。

按性能排序,是个好主意吗?想象一下,您每天有 10.000.000 名访问者(希望 :))

另一方面,我想知道你认为哪个数据库引擎更适合它,mysql?玛丽亚? MongoDB?

编辑:

想象一个更真实的场景:我需要 3 个连接来显示 POST + CATEGORY + USER_NAME。

POSTS: 50 million rows
CATEGORIES: 100 rows
USERS: 10 million rows

选项 A) 连接要显示的 3 个表:

[Baseball]
Hello World
- By John

选项 B) 将 2 列 (CAT_NAME, USER_NAME) varchar(25) 添加到 POSTS 表以避免连接。

【问题讨论】:

  • “我正在考虑将 CATEGORY_NAME 列添加到 POSTS 表中(当有人创建新帖子时),以避免每次访问时都必须进行 JOIN ......” - 那会被称为“非规范化”——除非你已经测量了性能问题,否则不要这样做。
  • 类别表听起来很小,因此对性能的影响应该很小(基本上是内存中的哈希查找)。如果有问题,我会在非规范化之前调查缓存(特别是因为类别名称可能很少更改)。
  • 但理论上它应该在高流量的情况下更快,对吧?我用第二种情况更新主帖。
  • 理论上是的。在实践中,没有。
  • 在实践中,增加每行的大小会减少磁盘上一个页面可以容纳的行数,从而增加 DBMS 必须加载和处理的页面数。不必担心连接,而是使用 EXPLAIN 来确保您的表为您正在运行的实际查询正确索引。

标签: php mysql database performance


【解决方案1】:

让事情正常化。

JOIN 的成本低于拥有更丰满的桌子所带来的成本。目前(少量数据)您看不到太大的性能差异。当表太大而无法在 RAM 中缓存时,规范化的性能优势将大放异彩。

【讨论】:

    猜你喜欢
    • 2011-05-18
    • 2014-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    相关资源
    最近更新 更多