Which query has better performance? [closed]
-
28-02-2021 - |
Question
I have 3 tables as follow:
class
id:bigint(PK)
name:varchar (unique)
principal:
id: bigint(PK)
pid:bigint
role:boolean
uniqueConstraint(pid, role)
entry:
cid: (FK, reference class)
pid: (FK, refernce principal)
object_id: bigint
code: tinyint
PK: (cid, pid, obj)
The query must check existence of a record in entry
using a parameter set.
suppose parameter set is as follow:
- class's name: Class#3
- principal id as user: 3
- principal id as role: 2
- object ID: 45
I wrote 2 queries, one using join and one using sub-query, but I don't know which one performs better in large scale production environment:
Query number 1:
select id
from entry
where pid in ( select id
from principal
where (pid=2 AND role)
OR (pid=3 AND !role))
AND cid = (select id
from class
where name='Class#3')
AND object_id=45
And query number 2:
select e.id
from class c
inner join entry e on e.cid=c.id
and c.name='Class#3'
inner join principal p on p.id=e.pid
and p.id in ( select id
from principal
where (pid=2 AND role)
OR (pid=3 AND !role))
where e.object_id=45
Of course there's an additional condition for checking code which I didn't include it in queries
Suppose there are 100 rows in class
, 10000 in principal
and over 250000 in 'entry', and query(as explained) must be executed for each request, and there are 3000 users working on system constantly and simultaneously
- Which of these queries will perform better And why? the reason is so important for further works
- Is there better approach to write the query than these 2 approaches or even better approach to construct the schema?
Regards
PS: I Have read this question about comparing sub-query and join, but my question is not exactly a simple comparison
UPDATED: fixed the role column name in principal
table
Solution
Often the simplest way to express the query will perform the best.
The following query should be close to optimal:
select e.id
from entry e
join class c on c.id = e.cid
join principal p on p.id = e.pid
where e.object_id = 45
and c.name = 'Class#3'
and (p.id = 2 and p.role or p.id = 3 and !p.role);
But a lot depends on your data and your indexing. Compare execution plans to be sure.