我经常读到图 dbms 非常适合社交网络。例如,instagram 或 linkedin 上的关注者。我读到如果查询涉及多个连接,SQL dbms 性能会降低,特别是如果连接的表很大。
SQL 数据库在连接下可能表现不佳的确切原因是什么?假设该followers
表在两个外键上都建立了索引。
查询:
SELECT DISTINCT f2.followed_id
FROM followers f1
JOIN followers f2 ON f1.followed_id = f2.follower_id
WHERE f1.follower_id = 4;
查询的执行计划:
HashAggregate (cost=253.84..257.23 rows=339 width=8)
Group Key: f2.followed_id
-> Nested Loop (cost=0.84..253.00 rows=339 width=8)
-> Index Only Scan using followers_pkey on followers f1 (cost=0.42..16.22 rows=19 width=8)
Index Cond: (follower_id = 4)
-> Index Only Scan using followers_pkey on followers f2 (cost=0.42..12.27 rows=19 width=16)
Index Cond: (follower_id = f1.followed_id)
所以我认为执行计划并没有表明没有完成复杂的操作。我读到的一件事是,在连接表时,数据库引擎需要在两个表中搜索匹配的行并将它们组合成一个结果集。这就是性能不佳的原因吗?
或者也许我错过了其他一些有效的观点?
您基本上是对的,您上面发布的查询(一个简单的连接、过滤器和聚合)可以在任何具有正确硬件和索引的体面的 RDBMS 中轻松处理。连接和过滤器本身对于现代 RDBMS 来说不是问题,这是一个古老的神话,主要由那些不知道如何正确索引的人传播。
然而,这不是图数据库擅长的查询类型。图形数据库将主要执行需要递归 CTE、复杂函数或游标才能在 SQL 中实现的查询类型,所有这些都比几乎所有 RDBMS 中的常规连接慢得多。
例如,一个典型的查询可能是:所有
followers
的id: 4
,递归地所有他们的followers
,其中每个至少有两个链接。使用 SQL 执行这样的查询非常困难且缓慢。您发布的计划可能并不复杂,但肯定会很慢。如果您的可见性地图未全部设置好,或者如果查询与您显示的选择多一列的查询略有不同,则可能需要对表和索引的随机页面进行 339 次串行读取。使用 5400 rpm 的硬盘并且没有可用的缓存,这将近 4 秒。
所以这个问题肯定是真实的。它可以通过确保仅索引扫描、缓存、SSD、可能是 effective_io_concurrency 或并行查询来解决。也许它也可以通过使用一些未命名的“图形数据库管理系统”来解决,我们怎么可能知道匿名产品的能力?