删除此JOIN可以获得性能提升吗?

mak*_*eee 5 mysql join

我有一个包含100万行的"items"表和一个包含20,000行的"users"表.当我从"items"表中选择时,我在"users"表(items.user_id = user.id)上进行连接,这样我就可以从users表中获取"username".

我正在考虑在items表中添加用户名列并删除连接.我可以期待从中获得不错的性能提升吗?它已经很快了,但减少我的负载(这是非常高的)会很好.

缺点是如果用户更改了他们的用户名,项目仍然会反映他们的旧用户名,但如果我能期望性能提升,那么这对我来说没问题.

我问stackoverflow因为基准测试并没有告诉我太多.两个查询都很快完成.无论如何,我想知道是否删除连接会在很大程度上减轻数据库的负担.

带连接的示例查询:
SELECT 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.modifiedFROM itemsAS ItemLEFT JOIN usersAS UserON( Item.submitter_id= User.id)WHERE Item.nofront!= 1 AND Item.removed!= 1 AND Item.made_popular不是NULL和裸露!= 1 ORDER BY Item.made_popularDESC LIMIT 1040,290;

没有连接的示例查询:
SELECT 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_dataitemsAS ItemWHERE Item.nofront!= 1 AND Item.removed!= 1 AND Item.made_popular不是NULL和裸露!= 1 ORDER BY Item.made_popularDESC LIMIT 1040,290;

pax*_*blo 5

正确的答案是在目标环境中测量它,看它是否有所作为.然后进行成本/收益分析,看看它是否值得.

成本是增加的存储空间和数据不同步的可能性(但请参见下文关于如何减轻这种情况).好处是提高速度或减少负载.

数据库模式不是一劳永逸的操作,它们应该随着底层数据的变化而定期调整.这就是DBA所付出的代价,持续监控和调整.

在任何情况下,通过使用触发器,可以在相当容易的DBMS中很容易地控制列的复制.通过这种方式,我的意思是在用户表上放置一个插入/更新触发器,这样,如果用户更改了用户名,它也会在items表中更改(反之亦然).

MySQL是否符合我对一个体面的DBMS的定义,我无法评论 - 我自己就是DB2.但是,从第三范式中恢复是一种久经考验的技术,用于将数据库中的每一个最后一次性能绞尽脑汁,并且只要您了解后果,就可以接受.很少有人抱怨他们的数据库占用了太多的磁盘空间.许多人抱怨他们的查询运行速度有多慢.

请记住,如果遇到性能问题,您可以执行恢复操作.这不应该只是因为你认为它可以减少负荷.除非负载(或所花费的时间)实际上是一个问题,否则您的成本/收益分析的利益部分为零,因此任何合理的bean计数器都会告诉您这意味着"没有变化".


根据您添加的查询,我有几点要做:

  • 首先是nudity专栏.请告诉我如何访问这个数据库:-)
  • 您应该提取所需的列.如果用户名是User表中所需的全部内容,则不应该在第一个查询中获得所有额外的内容.可能同样的Item东西 - 只能得到你需要的东西.
  • 确保在WHERE子句中使用的所有列上都有索引- 这可能还需要组合索引(具有多个列的索引).索引的内容取决于您的查询,但WHERE子句中使用的每个列都是分析的良好开端.
  • 对于大型表,您可以将定期"清除"已删除的项目视为单独的表(例如RemovedItems),以最小化Items查询的大小并加快查询速度.但请记住,这只有在您很少需要查找romoved项目时才有用,因为它会使这些查询复杂化(通过强制它们在两个表而不是一个表中搜索).同样,这是一个成本/收益的事情.一百万行并不是那么大的表(至少在我的世界里).