Tito Ciuro wrote:

Assume the following scenario: I store people in a table, like this:

People
    ROWID, idx
    GUID, idx
    First, idx
    Last, idx
    Email
    ...

In the app, the user can select People GUIDs from different sources and then retrieve the info from the database. The easy/suboptimal route to retrieve the records would be to perform a SELECT per GUID selected. I thought of something like this:

SELECT * FROM People where GUID in ("ABC", "RDT", "TUV");

Is there a better way to include all these GUIDs on a single SQL statement to speed things up?

Questions I have:

1) Is this the best way to solve the problem? Suggestions?

Tito,

You might want to use a temp table to hold your list of GUIDs. Then you can use a single precompiled query to do the select.

   select * from People where GUID in (select GUID from temp_guids)

As it is, you will have to prepare your query for each lookup. The temp table would replace the loop that binds the parameters with a loop that inserts the guids into the temp table.

Also, you are using double quotes for string literals, these should be single quotes instead.

   ... in ('ABC', 'RTD', 'TUV')

2) Is there a limit on the number of parameters I can pass to "in"? What if I have, say, 500 to retrieve? Will SQLite complain about this?


As far as I know there is no hard limit on the number of parameters you can use in a query. If you want to precompile the query you will need to have as many as your maximum requirement. In that case you will have to bind all the parameters before the query, and then reset them to null after the query so that the values are reset for the next query (i.e you will have to bind each variable twice). If you don't do this a query with many parameters followed by a query with a few will still have values bound to the higher numbered parameters left over from the first query.


In the alternate, temp table approach, you would create the table if it doesn't exist

   execute("begin")
   execute("create temp table if not exists temp_guids(guid primary key)")
Then loop to insert the GUIDs using a precompiled insert with one parameter

   s = prepare(insert into t values(?))
   for each guid in guid_list:
      bind(s, 1, guid)
      execute(s)

   execute ("commit")

Now execute your guid lookup query

people = execute("select * from People where GUID in (select guid from temp_guids)" And finally clear the temp table

   execute("delete from temp_guid")


Of course you would have to try each methods to see which is fastest. The single query requires compilation for each lookup, a single precompiled query requires binding each variable twice but has the advantage that the VDBE code will build an index from the parameters on the fly (without an associated table), the temp table approach can be done by executing only prepared sql statements but will build two records (one in the table and one in the index) for each record.

I seem to be rambling so I will stop now.

HTH
Dennis Cote
-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to