Re: [sqlite] Optimize a query

2007-04-17 Thread Martin Jenkins

Marco Bambini wrote:

This query on a small database sometimes takes more than 40 seconds:
select _rowid, public_id, vote_count, status, summary, component, 
date(date_modified), quickfix from reports where public = 1 AND _rowid 
IN (select distinct r._rowid from reports r, segments s where 
s.report_id = r._rowid AND r.public = 1 AND s.public = 1 AND (r.summary 
LIKE '%server%' OR s.content LIKE '%server%')) order by vote_count DESC


I'm no expert, but won't this bit

 LIKE '%server%' OR s.content LIKE '%server%')) order by vote_count

force the query to perform a full table scan regardless of the indexes?

What happens to the query speed if you (temporarily) change the LIKE 
clauses to look for a specific record?


Martin

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



Re: [sqlite] Optimize a query

2007-04-17 Thread Martin Pelletier

This is news to me. Why can't SQlite use more than one index?

Samuel R. Neff wrote:
afaik SQLite will only use one index per table 


--
Martin Pelletier
Informatique / Software Development
Infodev Electronic Designers International Inc.
Tel : +1 (418) 681-3539, poste /ext. 114
Fax : +1 (418) 681-1209


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



Re: [sqlite] Optimize a query

2007-04-17 Thread Paul Smith

At 16:46 17/04/2007, you wrote:

This is news to me. Why can't SQlite use more than one index?


Possibly because it's 'SQ *Lite*'?
The query optimiser in SQLite is a lot less powerful than in some 
other SQL databases - but then it's a fraction of the size as well...


Instead of having two indices on columns A and B, you need to 
consider having another index on both columns at once.


PaulVPOP3 - Internet Email Server/Gateway
[EMAIL PROTECTED]  http://www.pscs.co.uk/



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



Re: [sqlite] Optimize a query

2007-04-17 Thread drh
Martin Pelletier [EMAIL PROTECTED] wrote:
 This is news to me. Why can't SQlite use more than one index?
 

It can.  You just have to tell it to explicitly by restructuring
your SQL.  

As an example, consider this query:


 SELECT * FROM table1 WHERE a=5 AND b=11;

Suppose there are two indices:

 CREATE INDEX index1 ON table1(a);
 CREATE INDEX index2 ON table1(b);

As written, SQLite will only use one of these two indices
to perform the query.  The choice is arbitrary (unless you
have run ANALYZE and SQLite has some information to help it
pick the best index.)

If you want to use both indices, rewrite the query this
way:

 SELECT * FROM table1 WHERE rowid IN
 (SELECT rowid FROM table1 WHERE a=5
   INTERSECT SELECT rowid FROM table1 WHERE b=11);

The optimizer in PostgreSQL will make this change for you
automatically and will use a bitmap to implement the IN
operator and the INTERSECT.  With SQLite, though, you have to
type in the expanded version yourself.  And because rowids
in SQLite are user visible and changeable and can thus be
diffuse, SQLite is unable to use bitmaps to optimize the
computation.  But modulo the bitmap optimization, SQLite gives
you all the capabilities of PostgreSQL, you just have to type
it in yourself rather than letting the optimizer do it for
you.

--
D. Richard Hipp [EMAIL PROTECTED]


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



[sqlite] Optimize a query

2007-04-17 Thread Marco Bambini

This query on a small database sometimes takes more than 40 seconds:
select _rowid, public_id, vote_count, status, summary, component, date 
(date_modified), quickfix from reports where public = 1 AND _rowid IN  
(select distinct r._rowid from reports r, segments s where  
s.report_id = r._rowid AND r.public = 1 AND s.public = 1 AND  
(r.summary LIKE '%server%' OR s.content LIKE '%server%')) order by  
vote_count DESC


Table reports contains 22,605 records
Table segments contains 71,413 records

I suspect that the slowdown is due to the IN clause used in the query  
or something else that prevents sqlite from using some optimizations.

Anyone can help me to optimize this query?

Details follows...

TABLES:

CREATE TABLE reports (_rowid integer NOT NULL PRIMARY KEY, vote_count  
integer DEFAULT 0, summary varchar(256), public integer DEFAULT 0,  
date_created date, locked_by integer DEFAULT 0, public_id varchar 
(16), component integer, severity varchar(32), priority integer  
DEFAULT 0, user_id integer, release_note_id integer DEFAULT 0, type  
integer DEFAULT 0, date_modified timestamp, fixed_version varchar 
(16), status integer DEFAULT 0, quickfix integer DEFAULT 0, easyfix  
integer DEFAULT 0)


CREATE TABLE segments (_rowid integer not null primary key  
autoincrement, type integer, public integer default 0, date_created  
date, content varchar(4096), date_modified date, report_id integer,  
user_id integer)


INDEXES:
CREATE INDEX reports_component_idx on reports (component)
CREATE UNIQUE INDEX reports_public_id_idx on reports (public_id)
CREATE INDEX reports_public_idx on reports (public)
CREATE INDEX reports_status_idx on reports (status)
CREATE INDEX reports_summary_idx on reports (summary)
CREATE INDEX reports_user_id_idx on reports (user_id)
CREATE INDEX segments_content on segments (content)
CREATE INDEX segments_public on segments (public)
CREATE INDEX segments_report_id on segments (report_id)
CREATE INDEX segments_type on segments (type)
CREATE INDEX segments_user_id on segments (user_id)

Thanks a lot,
---
Marco Bambini




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



RE: [sqlite] Optimize a query

2007-04-17 Thread Samuel R. Neff
afaik SQLite will only use one index per table so if you have a where clause
WHERE public = 1 and _rowid IN (...)  it will use an index on public and
not _rowid.  Swapping the  where clause around should have a significant
impact:

select 
_rowid, 
public_id, 
vote_count, 
status, 
summary, 
component, 
date 
(date_modified), 
quickfix 
from 
reports 
where 
_rowid IN  (
select distinct r._rowid 
from reports r, segments s 
where  
s.report_id = r._rowid 
AND r.public = 1 
AND s.public = 1 
AND  (r.summary LIKE '%server%' OR s.content LIKE
'%server%')
) 
AND public = 1
order by  vote_count DESC


but really the public = 1 where clause on the outer query doesn't look
necessary since you already are checking public = 1 in the inner query.

Also, formatting SQL statements so they aren't a huge blob of sql will make
them easier to read, especially for mailing lists.  :-)

HTH,

Sam

---
We're Hiring! Seeking a passionate developer to join our team building
products. Position is in the Washington D.C. metro area. If interested
contact [EMAIL PROTECTED]
 


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



Re: [sqlite] Optimize a query

2007-04-17 Thread bartsmissaert
Interesting and thanks for that tip.
Is there a performance penalty from structuring the
query like that? I take it that there will be.

RBS


 Martin Pelletier [EMAIL PROTECTED] wrote:
 This is news to me. Why can't SQlite use more than one index?


 It can.  You just have to tell it to explicitly by restructuring
 your SQL.

 As an example, consider this query:


  SELECT * FROM table1 WHERE a=5 AND b=11;

 Suppose there are two indices:

  CREATE INDEX index1 ON table1(a);
  CREATE INDEX index2 ON table1(b);

 As written, SQLite will only use one of these two indices
 to perform the query.  The choice is arbitrary (unless you
 have run ANALYZE and SQLite has some information to help it
 pick the best index.)

 If you want to use both indices, rewrite the query this
 way:

  SELECT * FROM table1 WHERE rowid IN
  (SELECT rowid FROM table1 WHERE a=5
INTERSECT SELECT rowid FROM table1 WHERE b=11);

 The optimizer in PostgreSQL will make this change for you
 automatically and will use a bitmap to implement the IN
 operator and the INTERSECT.  With SQLite, though, you have to
 type in the expanded version yourself.  And because rowids
 in SQLite are user visible and changeable and can thus be
 diffuse, SQLite is unable to use bitmaps to optimize the
 computation.  But modulo the bitmap optimization, SQLite gives
 you all the capabilities of PostgreSQL, you just have to type
 it in yourself rather than letting the optimizer do it for
 you.

 --
 D. Richard Hipp [EMAIL PROTECTED]


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







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