简体   繁体   中英

Any way to faster sql query containing IN clause where data for IN clause is obtained from with in a query?

During my project, I came across a requirement where I need to process some operation over some address which is not present inside some other table, and for that, I have written the following query. But I think this query will go slow when the entries in the second table 'transaction' increases.

select emp_address
from emp_leave_wallet
where attached  ="mycompany_wallet" and
      emp_address not in (select destination_address from transaction);

Any other way, other than adding Index over destination_address.

A solution using a JOIN but I can't quantify the performance gain:

SELECT ew.emp_address
FROM emp_leave_wallet ew
LEFT OUTER JOIN transaction t on
    t.emp_address = ew.emp_address
WHERE ew.attached = "mycompany_wallet" and
      t.emp_address IS NULL

I would start with not exists :

select lw.emp_address
from emp_leave_wallet lw
where lw.attached  = 'mycompany_wallet' and
      not exists (select 1
                  from destination_address da
                  where lw.emp_address = da.destination_address 
                 );

Then for this query you definitely want an index on destination_address(destination_address) and probably on (attached, emp_address) .

Use not exists :

select ew.emp_addres
from emp_leave_wallet ew
where ew.attached = "mycompany_wallet" and
      not exists (select 1 from transaction t where t.destination_address = ew.emp_address);

Use NOT EXISTS which returns record if there is no matching row in transaction table based on where condition:

select emp_address
from emp_leave_wallet e
where attached = 'mycompany_wallter'
  and not exists (
    select 1
    from transaction t
    where e.emp_address = t.destination_address
    )

Create indexes:

CREATE INDEX idx1 ON emp_leave_wallet(attached, emp_address);
CREATE INDEX idx2 ON transaction(destination_address);
select emp_address
from emp_leave_wallet
where attached  ="mycompany_wallet" and
      emp_address not in (select destination_address from transaction);

Your emp_leave_wallet and transaction table should have id fields (I'm guessing ... emp_id , transaction_id )

If it were me i would...

select emp_address
from emp_leave_wallet elw
inner join transaction t
on elw.emp_id = t.transacation_id

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM