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

  1. Which of these queries will perform better And why? the reason is so important for further works
  2. 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

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top