Also keep in mind that typical Dgraph workloads request specific attributes (think "SELECT NAME, AGE") rather than everything ("SELECT *"), which reduces the impact of fanout. :)
Those can be done concurrently if at the same query level, so not necessarily any slower. In other terms, the number of network calls required (in a sufficiently distributed cluster, where each predicate/attribute is on a different server), is proportional to the number of attributes asked for in the query, not the number of results (at any step in graph traversal).
And that's the big part of the design. By constraining the number of network calls to very few machines, while doing traversals, which would lead to millions of results in the intermediate steps -- Dgraph can deal with high fan-out queries (with lots of node results) much better.
Alternative would be to shard by nodes (entities) -- in which case, if the intermediate steps have millions of results, they could end up broadcasting to the entire cluster to execute a single query. That'd kill latency.
So, the problem is not how many attributes a query is asking for -- that's generally bounded. The problem is how many nodes you end up with as you traverse the graph, those could be in millions.
That's why many graph layer systems suck at doing anything deeper than 1 or 2 level traversals / joins.
> Those can be done concurrently if at the same query level, so not necessarily any slower.
An important clarification, yes! I should have made that more explicit. :)
Imagine, in an abstract way, that it is a hashing process. Where the attributes are spread over several instances in the cluster and Dgraph just "decodes" it for you quickly because it already has the key.
Could it be based on entities? yes, but I don't think it would bring any benefit. Imagine that you have 10 instances, and you have 10 entities. You have 3 entities with many edges (values and outgoing edges) and 8 "light" entities, without much information. Well, you will leave 3 entities in high usesage of resources while 8 entities are idle because they do not have much information to deliver to all query and mutation requests in the Cluster.
A system based on attributes in a distributed way is much more performance tho.
> Naively, I'd think that one would cluster by entity and what an entity is connected to
In a distributed system, that approach leads high-fanout and network broadcasts, which kills query latency. Ideally, you want to do a traversal / join in one network call (max), not more. Because of this design, Dgraph can execute arbitrary depth queries in a much faster way. More details are in [1].
I know almost nothing about graph databases, so presumably this is just my ignorance. But if entity-focused retrieval is an important use case, isn't clustering by attribute going to kill performance? Naively, I'd think that one would cluster by entity and what an entity is connected to.