What are the advantages/disadvantages of using EXISTS vs. IN?
As an example, is it better to do something like
SELECT * FROM MainTable WHERE MainTable.categorynum IN (SELECT num FROM Categories WHERE category = 'Real')
Or
SELECT * FROM MainTable WHERE EXISTS (SELECT 1 FROM Categories WHERE MainTable.categorynum = Categories.num AND Categories.category = 'Real')
As far as I can tell, these two queries do very very similar things and I'm wondering what, if any, difference there is (are there certain situations whether it is better to use one or the other?)
[EDIT] Changed the queries so they'd be a little less contrived ;)
As an example, is it better to do something like
SELECT * FROM MainTable WHERE MainTable.categorynum IN (SELECT num FROM Categories WHERE category = 'Real')
Or
SELECT * FROM MainTable WHERE EXISTS (SELECT 1 FROM Categories WHERE MainTable.categorynum = Categories.num AND Categories.category = 'Real')
As far as I can tell, these two queries do very very similar things and I'm wondering what, if any, difference there is (are there certain situations whether it is better to use one or the other?)
[EDIT] Changed the queries so they'd be a little less contrived ;)
no subject
Date: 2006-07-19 05:02 pm (UTC)I do not know what database this is, but a lot of them also have a limit to the number of values you can put in an "in" clause (Oracle gives an error when the number is over 1000).
Since I am guessing this is primary key to foreign key the join should cost almost nothing in system resources (even if it is not, it will still take less resource to do the join select, than the IN in my experense)
Just my 2 cents :)
no subject
Date: 2006-07-19 05:07 pm (UTC)Just make your two tables, and run 1000 tests on each and see which ones take longer ^_^
no subject
Date: 2006-07-19 06:23 pm (UTC)no subject
Date: 2006-07-19 06:12 pm (UTC)Would that be something like:
SELECT * FROM MainTable
INNER JOIN Categories ON MainTable.categorynum = Categories.num
INNER JOIN Statuses ON MainTable.statusnum = Statuses.num
WHERE Categories.category = 'Real' AND Statuses.status = 'Active'
(I'm currently running against an Oracle database)
no subject
Date: 2006-07-19 06:18 pm (UTC)select M.* from mainTable M, Categories C, Statuses S
where M.categorynum = C.categorynum
and M.statusnum = S.statusnum
and C.category='Real' and S.status = 'Active'
You do not need to state inner joins in oracle as they are implied, you only need to state outerjoins.
You can also aliast a table name to something else easler to type (like I did above). It is also an easy way to have a table link to itself (with aliases).
no subject
Date: 2006-07-19 06:49 pm (UTC)From the article (on SQL server, but the same logic will work with oracle as well) Optimization of SQL statements
When you have a choice of using the IN or the EXISTS clause in your Transact-SQL, you will generally want to use the EXISTS clause, as it is usually more efficient and performs faster. [6.5, 7.0, 2000] Updated 10-30-2003
As a side note, if the categorynum and statusnum are known ahead of time, and do not change, you can remove the need to do any joins.
As for which is faster.....
It will all depend on how the indexes are set up, and how many values are in all of the tables.
I am getting the feeling you would be better off just coding in the Categoriesnum and statusnum in the query and not doing a join at all, and just doing the two equal calls in the where statement
no subject
Date: 2006-07-19 05:21 pm (UTC)uhm...
~thinks~
can we just go get ice cream now? my brain hurts!
no subject
Date: 2006-07-19 06:04 pm (UTC)