sql-server - 如何提高 SQL 数据库的多重 JOIN 性能
问题描述
假设我有一个喜欢 Spotify 的应用程序,并且架构如下:
用户登录后,点击我的歌曲按钮,查询需要返回该用户购买的所有歌曲。
根据上面的架构,我需要编写如下 SQL:
select s.name, al.name, ar.name, g.genres
from users u
join purchases p on u.id = p.userid
join purchaseitem pi on p.id= pi.purchaseid
join songs s on pi.itemid = s.id
join albums al on al.id = s.albumid
join genres g on g.id = s.genreid
join artists ar on ar.id = al.artisted
这种丑陋的多连接查询可能会导致严重的性能问题。
我们可以对查询本身做哪些增强?
如果我们对 SQL 查询无能为力,如何重新设计数据库模式以增强这种能力?
如果我们能够对SQL数据库进行分区,即索引,是否有助于提高性能?
如果性能是唯一的考虑因素,那么像 Cassandra 或 MongoDB 这样的 NoSQL 数据库会是更好的选择吗?
解决方案
您可以对购买项目表进行非规范化,并将所有其他数据(专辑名称、艺术家姓名等)保留在购买项目表中。一旦购买完成,数据将不会改变。
例如,如果您在购买后更改艺术家姓名怎么办。然后稍后您的报告将有一个新的艺术家姓名,但在购买时该艺术家的姓名不存在。
您不需要在系统中保留购买历史记录。?
然后你可以简化这个采石场,但你必须考虑你的整体设计,这可能是你解决方案中的一个采石场。当你冗余数据时,你必须确保你在系统中有正确的控制。规范化关系数据库中的所有数据没有硬性规定。
您可以通过非规范化表来提高读取性能,但它会影响插入和更新。您需要平衡这些与您的要求
选择 NOSQL 不会是灵丹妙药。您可以通过适当的设计在关系数据库系统中处理数百万条记录。此外,微服务模式可用于可扩展性,但它会使您的设计和技术堆栈复杂化。
推荐阅读
- git - git pre-receive 钩子无法为服务器上的其他存储库执行 git 命令
- react-native - 如何在@shoutem/ui DropDownMenu 中设置最后一项不透明?
- vb.net - 找到新结果时更改 ListView 状态
- html - 空列表 LXML XPATH
- kotlin - 当我在 KorGE 中切换到其他场景时出现异常
- ios - 通知服务扩展是否需要任何功能?
- javascript - 如何获取触发了 jstree 上下文菜单的节点?
- c# - 尝试使用 Canvas Bitmap 将 C# 中的图片保存到字节数组,但它只输出 2^16 个字节
- python - 其他文件中的函数
- redis - Redis Exporter:Redis 上 Prometheus 的加密端口是什么?