我有一个包含 100 万行的“项目”表和一个包含 20,000 行的“用户”表。当我从“items”表中选择时,我会在“users”表上进行连接(items.user_id = user.id),这样我就可以从用户表中获取“用户名”。
我正在考虑向项目表中添加一个用户名列并删除连接。我可以期望由此带来可观的性能提升吗?它已经相当快了,但是减少我的负载会很好(这是相当高的)。
不利的一面是,如果用户更改了他们的用户名,项目仍然会反射(reflect)他们的旧用户名,但是如果我可以期待一个不错的性能提升,这对我来说是可以的。
我问的是 stackoverflow,因为基准测试并没有告诉我太多。这两个查询都很快完成。无论如何,我想知道删除连接是否会在很大程度上减轻数据库的负载。
带连接的示例查询:
选择 Item
. id
, Item
. submitter_id
, Item
. source_image
, Item
. cached_image
, Item
. source_title
, Item
. source_url
, Item
. width
, Item
. height
, Item
. status
, Item
. popular
, Item
. made_popular
, Item
. fave_count
, Item
. tags
, Item
. user_art
, Item
. nudity
, Item
. created
, Item
. modified
, Item
. removed
, Item
. nofront
, Item
. test
, Item
. recs
, Item
. recs_data
, User
. id
, User
. username
, User
. password
, User
. email
, User
. fullname
, User
. profileurl
, User
. homepage
, User
. bio
, User
. location
, User
. avatar
, User
. ff_user
, User
. ff_key
, User
. ff_last_faveid
, User
. twitter_user
, User
. twitter_pass
, User
. emailalerts
, User
. showunsafe
, User
. view
, User
. fb_uid
, User
. fb_session
, User
. fb_avatar
, User
. twitter_uid
, User
. twitter_data
, User
. twitter_autopost
, User
. uri
, User
. created
, User
. modified
发件人 items
AS Item
左连接 users
AS User
ON ( Item
. submitter_id
= User
. id
) WHERE Item
. nofront
!= 1 AND Item
. removed
!= 1 AND Item
. made_popular
不是 NULL 和裸体 != 1 ORDER BY Item
. made_popular
DESC 限制 1040, 290;
没有连接的示例查询:
选择 Item
. id
, Item
. submitter_id
, Item
. source_image
, Item
. cached_image
, Item
. source_title
, Item
. source_url
, Item
. width
, Item
. height
, Item
. status
, Item
. popular
, Item
. made_popular
, Item
. fave_count
, Item
. tags
, Item
. user_art
, Item
. nudity
, Item
. created
, Item
. modified
, Item
. removed
, Item
. nofront
, Item
. test
, Item
. recs
, Item
. recs_data
发件人 items
AS Item
哪里Item
. nofront
!= 1 AND Item
. removed
!= 1 AND Item
. made_popular
不是 NULL 和裸体 != 1 ORDER BY Item
. made_popular
DESC 限制 1040, 290;
最佳答案
正确的答案是在目标环境中测量它,看看它是否有所作为。然后进行成本/ yield 分析,看看是否值得。
成本是增加的存储和数据不同步的可能性(但请参阅下文了解如何缓解这种情况)。好处是速度增加或负载减少。
数据库模式不是一劳永逸的操作,它们应该随着底层数据的变化而定期调整。这就是 DBA 的报酬,持续监控和调整。
在任何情况下,通过使用触发器,在一个不错的 DBMS 中可以很容易地控制列的重复。我的意思是在 users 表上放置一个插入/更新触发器,这样,如果用户更改了他们的用户名,它也会在 items 表中更改(反之亦然)。
MySQL 是否符合我对一个体面的 DBMS 的定义,我无法发表评论——我自己就是一个 DB2。但是,从第三范式恢复是一种久经考验的技术,用于榨取数据库的每一分性能,并且如果您了解后果,则是完全可以接受的。很少有人提示他们的数据库占用了太多的磁盘空间。许多人提示他们的查询运行速度太慢。
请记住,当您遇到性能问题时,您需要执行还原操作。这不是因为您认为它可能会减少负载而应该做的事情。除非负载(或花费的时间)实际上是一个问题,否则您的成本/ yield 分析的 yield 部分为零,因此任何理智的 bean 计数器都会告诉您这意味着“没有变化”。
根据您添加的查询,我有几点要说明:
nudity
柱子。请告诉我如何访问这个数据库:-) User
表,你不应该在第一个查询中得到所有额外的东西。可能同样适用于 Item
东西 - 只得到你需要的东西。 WHERE
中使用的所有列都有索引子句 - 这也可能需要组合索引(具有多于一列的索引)。索引的内容取决于您的查询,但 WHERE
中使用的每一列从句是分析的良好开端。 RemovedItems
)以最小化 Items
的大小。并加快查询速度。但是请记住,这仅在您很少需要查找已移动项目时才有用,因为它会使这些查询复杂化(通过强制它们在两个表中而不是一个表中进行搜索)。同样,这是一个成本/ yield 的事情。一百万行并不是那么大的表(至少在我的世界中)。 关于mysql - 删除此 JOIN 是否可以提高性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2597407/