I’m working on a rights verification system.
In order to verify that the user has access to the documents, I make a request to the database
There are 2 cases when you can get access:
- The user is in the access zone of this document
(for example, a user in the chat where the document was published)
select count(*) > 0 from Document
left join Chat
left join ChatUser
left join User
left join Resource
...
where ...
- The document is public
select count(*) > 0 from Document
left join User
left join Resource
left join ...
...
where ...
I see 2 solutions
- Make a request covering both cases (union)
pros of such a solution -> 1 request to the database
cons of such a solution -> every time in 70% of cases I make an extra 5 joins, which can hit the performance of the query in the database
- Make 2 requests
First make a request whether the document is in the chat.
If false -> then make 1 more request
Tell me what algorithm is used in such cases?
2
Answers
If you have one-to-one relation then join queries should be used.
Join queries with one-to-many relation will lead to more memory usage with redundant data.
If you don’t have memory usage issue then also you should use join queries because in most of the cases, join queries are faster than multiple queries.
If you think that network-latency will be a deal-breaker, why not offload the ‘if not found at first, try second query’ in a plsql-function? You’d only need to query the function once and it will return you a boolean. Heck, you could easily add another flag indicating whether it found it in the chat or needed to check out the public one too if your app needs that info.
That said, you probably can gain quite a bit of performance by rewriting your query from
To
This way the system doesn’t need to check all situations that apply but can stop at the first match.
I also find it strange that you have
LEFT OUTER JOIN
s in there rather thanINNER JOIN
s but that might be simplification for putting it on StackOverflow, right?I’m actually wondering if just merging the two queries using
WHERE EXISTS()
would not make the optimizer do the ‘only if not found at first do the second part’ … theEXPLAIN ANALYZE
should make that quite clear. Use https://explain.dalibo.com/ or something like that to make it easier to interpret.So, it would become this: