Thanks for your reply. 
I've tried running versions of query that you suggested and got following
results:


Originally posted version       4.5 sec
Version with only first-part of where clause    16 ms 

Rewritten version without joins runs in 6.5 seconds
Version with unions runs in     15ms

Creating multi-column index (source.id, target.id) 4.5 sec
Removing all indexes for source.id and target.id        4.5 sec
Running query with first part of where clause and no indexes    2.5 sec


So it seems that indexes are not used at all, and that is pretty strange

I didn't state it in my original post, but this query was automatically
generated by object relational-mapper, that generates hundreds of similar
queries. I see that replacement of OR with UNION and AND with INTERSECT will
probably solve the problem, but yet it seems that using OR and AND in WHERE
clause is a better way to write queries, especially with complex nested
conditions. 


Some information on db:
About 1500 records in each table
Original query returns about 10 rows


Any suggestions on why indexes are not used and how to make SQLite use them
for this query?

-----Original Message-----
From: Dennis Cote [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, May 02, 2007 6:58 PM
To: sqlite-users@sqlite.org
Subject: Re: [sqlite] FW: Performance problem with complex where clause

Александр Прокофьев wrote:
> I'm running a query against sqlite database and it runs very slow - about
5
> seconds(on larger database it can ran for a whole minute). 
>
>  
>
> Select [Node_Entity].* From [Node] AS [Node_Node] JOIN [Entity] AS
> [Node_Entity] ON [Node_Node].LOCAL_ID = [Node_Entity].LOCAL_ID , [Link] AS
> [Link_Link] JOIN [Entity] AS [Link_Entity] ON [Link_Link].LOCAL_ID =
> [Link_Entity].LOCAL_ID 
>
>  
>
> Where (( 
>
> (([Link_Link].[Target.Id]='06d15df5-4253-4a65-b91f-cca52da960fe') AND
> ([Link_Link].[Source.Id]=[Node_Entity].[Id]))
>
>  
>
>       OR (([Link_Link].[Target.Id]=[Node_Entity].[Id]) AND
> ([Link_Link].[Source.Id]='06d15df5-4253-4a65-b91f-cca52da960fe'))
>
>      ))
>
>  
>   
You have an unnecessarily complicated query. First I re-wrote your query 
using standard quotes and eliminated the unnecessary quotes and 
brackets. I also replaced the alias names with something shorter to make 
the existing query clearer.

    Select ne.*
    From Node AS n
    JOIN Entity AS ne ON n.LOCAL_ID = ne.LOCAL_ID
    JOIN Link AS l
    JOIN Entity AS le ON l.LOCAL_ID = le.LOCAL_ID
    Where l."Target.Id" = '06d15df5-4253-4a65-b91f-cca52da960fe'
        AND l."Source.Id" = ne.Id
    OR l."Target.Id" = ne.Id
        AND l."Source.Id" = '06d15df5-4253-4a65-b91f-cca52da960fe'

Now it is clear that you are joining two tables that are not referenced 
by the query at all. The node table and the second join on the entity 
table (which you called link entity) are not needed. After these are 
removed you have an equivalent but much simpler query. Note, I also 
rearranged the terms in the second half of the OR clause to be in the 
same order as the first half.

    Select ne.*
    From Entity AS ne
    Join Link AS l
    Where l."Target.Id" = '06d15df5-4253-4a65-b91f-cca52da960fe'
        AND l."Source.Id" = ne.Id
    OR l."Source.Id" = '06d15df5-4253-4a65-b91f-cca52da960fe'
        AND l."Target.Id" = ne.Id

It might be clearer to yet separate the two halves of this query and 
combine the results using a union.

        Select ne.*
        From Entity AS ne
        Join Link AS l on l."Source.Id" = ne.Id
        Where l."Target.Id" = '06d15df5-4253-4a65-b91f-cca52da960fe'
    UNION
        Select ne.*
        From Entity AS ne
        Join Link AS l on l."Target.Id" = ne.Id
        Where l."Source.Id" = '06d15df5-4253-4a65-b91f-cca52da960fe'

This should run in a reasonable time given that you have indexes on 
Link("Target.Id") and Link("Source.Id")

HTH
Dennis Cote


----------------------------------------------------------------------------
-
To unsubscribe, send email to [EMAIL PROTECTED]
----------------------------------------------------------------------------
-


-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to