Do either of these tables have any rows with NULL as a value for 'serial'?
A NOT IN predicate will test all the rows in the subquery for inequality, and if any values are NULL, the test will fail, so the predicate will be FALSE, and no rows are returned.
And you are generally correct that a JOIN is faster than a subquery, but you may find that the optimizer will generate identical plans in many cases. For example, a correlated subquery is almost always indistingushable from a JOIN.
And you'd generally be better off using EXISTS instead on IN with a subquery, since EXISTS may be better able to make use of indexes, whereas IN almost always results in a table scan or the creation of a temporary representing the subquery, which will not have any indexes and so may be slower.
Jeff Mason
Custom Apps, Inc.
www.custom-apps.com