Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

Do you have an index on invoices(ordno)? Are both columns (in the two tables) of the same datatype?
–
ypercubeSep 11 '12 at 6:29

1

MySQL should run that sub-select only once (as it is unrelated to the main query). Are you sure it's optimizer really handles it that badly?
–
a_horse_with_no_nameSep 12 '12 at 6:57

@ypercube You're right. The datatype in both coulmns is different. One is varchar another is integer. Could you explain why that creates the problem and put it as an answer so that I can select it.
–
Kshitiz SharmaSep 12 '12 at 8:28

SELECT
ordno
FROM
orders
WHERE
ordno NOT IN (SELECT DISTINCT ordno FROM invoices) ;

... but there is absolutely no reason to do it, if there is an index on invoices(ordno). You can test of course, but the explain plan should be the same and the execution times identical.

(the situation may be different if the invoices is not a base table but a complex view that returns thousands of identical order numbers).

You should also check if the two variations proposed in other answers are more efficient with your data distribution. I wouldn't expect much difference. This blog article Explain Extended: NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL: MySQL has some tests that support that but it's never bad to test with your data and table sizes, in your envirorment.

What you should really check first of all, is whether you have an index on orders(ordno) and on invoices(ordno) and whether these two columns, are of the same datatype.

If there are no indices, add them. If the two columns are of different datatype, change them into the same datatype.

The distinct in the sub-query will (should) not make any difference.
–
a_horse_with_no_nameSep 12 '12 at 6:56

IN ( SELECT ... ) is very poorly optimized (until about 5.6.7); do not use it. EXISTS ( SELECT ... ) is reasonably well optimized. LEFT JOIN ... IS [NOT] NULL is also well optimized.
–
Rick JamesJan 8 '13 at 1:27

@RickJames: NOT IN (SELECT ...) and IN (SELECT ...) are two different things with different optimizations.
–
ypercubeJan 8 '13 at 12:44