Is one of those solutions objectively better, or it all depends on the data? Explain option shows me that indeed, the optimizer does the query differently. This is just an example, I'm going to have lot's of such queries in my application, and I want to know the best way to perform such filtering.
SELECT *
FROM
(SELECT expand(in('hasPermission'))
FROM Permission
WHERE type IN ['USER'])
WHERE
login >="admin"
ORDER BY
login ASC
LIMIT 3
SELECT *
FROM User
WHERE login >= "admin"
AND out("hasPermission").type IN ["USER"]
ORDER BY login ASC
LIMIT 3
It depends a lot on the domain. Consider that the query optimizer in v 2.2 just starts scanning (or querying an index on) the target class (Permission in the first query, User in the second one) and then proceeds with traversing.
The first query is more efficient if you have few Permission records that have "USER" in type
attribute and if the number of incoming edges per permission is low. Even better if you have an index on type
The second query is more efficient if you have few users with login
> "admin" (again, with an index likely) and if the number of outgoing edges per single user is low.