Reputation: 7316
I need to retrieve records that match IDs stored in a list. The query, generated at runtime, is simple:
SELECT [whatever FROM sometable] WHERE (id = 1) or (id = 5) or (id = 33).
Which is equivalent to
SELECT [whatever FROM sometable] WHERE [id] IN (1, 5, 33);
This is fine, but what if the list contains hundreds or thousands of IDs? The statement will be huge and at some point the SQL parser might croak, or if it does not, performance will probably be quite bad. How can I do this in a way that is not so sensitive to the number of records being retrieved?
(The reason I can't just loop over the list and retrieve records one by one is that I need the database to do ORDER BY for me. Records must come from the DB ordered by a specific field, while the list represents records selected by the user in a grid which can be sorted in any number of ways. And yes, I could sort the records in code after I retrieve them, but that's plan B, since I don't even need to hold them all in one data structure, only to come properly ordered.)
Upvotes: 3
Views: 3125
Reputation: 881553
If you're really going to have so many IDs that you're worried about the SQL parser croaking, you can store them into a temporary table and do a cross-join.
Simply create the table with one (primary key) column, the ID, then populate it with the desired IDs and use something like:
SELECT [whatever] FROM [sometable] st, [idtable] it
WHERE st.id = it.id
That query won't choke any parser and the rows retrieved will be limited to those having the ID in the temporary table.
This doesn't have to be a temporary table, of course, you can leave it lying around provided you ensure only one "thing" uses it at a time.
Upvotes: 5
Reputation: 25966
Your programming language should support prepared queries, i.e.
SELECT [whatever FROM sometable] WHERE (id = ?);
or:
SELECT [whatever FROM sometable] WHERE (id = @id);
By preparing a query, the query is available for repeated used and you can bind the parameters to a variable in your native programming language. If this search is high frequency, its worthwhile to keep these prepared queries for some duration.
There's a useful discussion here:
Upvotes: 0
Reputation: 1431
Could you add these items to a table and then join to it?
SELECT Whatever FROM TableA CROSS JOIN TableB ON TableA.ID = TableB.ID
Upvotes: 1
Reputation: 2420
If the values in your where clause are in a table you can do this.
select id from foo where id in (select id from bar)
Upvotes: 0
Reputation: 23263
Presumably there is some logic involved in determining the list of ids to retrieve, could this logic not be incorporated into the where clause? Perhaps you could join to a table that contains some kind of session id along with the required ids?
Upvotes: 0