Andy
I get this explain output:

order|from|detail
0|0|TABLE mediaitem AS a WITH INDEX mediaitem_type
1|1|TABLE mediaitem AS b WITH INDEX mediaitem_type
2|2|TABLE container AS w USING PRIMARY KEY
3|3|TABLE container AS x USING PRIMARY KEY
4|4|TABLE container AS y USING PRIMARY KEY
5|5|TABLE container AS z USING PRIMARY KEY

Media Item Type is a terrible index! It only has 3 values so drop it.

After dropping the index i get this explain:

drop index mediaitem_type
   ...> ;
sqlite> .read media.sql
order|from|detail
0|0|TABLE mediaitem AS a WITH INDEX mediaitem_title ORDER BY
1|1|TABLE mediaitem AS b WITH INDEX mediaitem_containerID
2|2|TABLE container AS w USING PRIMARY KEY
3|3|TABLE container AS x USING PRIMARY KEY
4|4|TABLE container AS y USING PRIMARY KEY
5|5|TABLE container AS z USING PRIMARY KEY

See if that is better?



Andy Smith <[EMAIL PROTECTED]> wrote: I have to get this down to < 1 sec. I 
have 50 queries that are all
formatted similar.  We have created another schema where the container
is split into smaller tables which might help in speeding this up.  From
what I see the Left joins are killing the speed.

Here is what I am seeing when running explain query plan:

sqlite> explain query plan SELECT a.id, a.title, a.type, a.dateAdded,
a.url, a.path, a.containerID, a.mimeType, a.width, a.height, a.genreID,
a.thumbnailID, a.releaseYearID, a.artistID, w.title AS containerName,
x.title AS genreName, y.title AS releaseYearName, z.title AS artistName
FROM mediaitem AS a LEFT JOIN mediaitem AS b ON
b.containerID=a.containerID LEFT JOIN container AS w ON
w.id=a.containerID LEFT JOIN container AS x ON x.id=a.genreID LEFT JOIN
container AS y ON y.id=a.releaseYearID LEFT JOIN container AS z ON
z.id=a.artistID WHERE a.type=1 AND b.type=0 AND b.title LIKE 'Opus%'
ESCAPE '\' ORDER BY a.title, a.id LIMIT 0,9;

0|0|TABLE mediaitem AS a WITH INDEX mediaitem_title ORDER BY
1|1|TABLE mediaitem AS b WITH INDEX mediaitem_containerID
2|2|TABLE container AS w USING PRIMARY KEY
3|3|TABLE container AS x USING PRIMARY KEY
4|4|TABLE container AS y USING PRIMARY KEY
5|5|TABLE container AS z USING PRIMARY KEY

Schema:

sqlite> .schema
CREATE TABLE "container" (
-- fundamental container information
    "id"           INTEGER      PRIMARY KEY AUTOINCREMENT,
    "title"        VARCHAR(255) NOT NULL,
-- enumerations
--   10: music album
--   11: music artist
--   12: music genre
--   13: music composer
--   14: music conductor
--   15: release year
--   16: photo roll
--   17: photo album / slide show
--   18: events
--   19: keyword
--   20: people
--   21: places
--   22: user-defined tag
--   23: playlist
--   24: video season
--   25: video series
--   26: channel
--   27: director
--   28: actor
--   29: producer
--   30: audio series
--   31: media folder

    "type"           INTEGER      NOT NULL,
    "dateAdded"      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,
    "dateCreated"    TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,

-- generic information about the media container
    "details"        TEXT         DEFAULT NULL,-- lyrics, plot, etc.
    "detailsURI"     TEXT         DEFAULT NULL,-- lyrics, plot, etc.

-- non-NULL only for slideshows and playlists
    "duration"       INTEGER UNSIGNED
                                  DEFAULT NULL,-- in seconds
    "transition"     tinyint      DEFAULT '0', -- 0: no effect
                                               -- 1: fade in/out

-- non-NULL only for media folders
    "upnpShared"     tinyint      DEFAULT '0',
    "parentalLocked" tinyint      DEFAULT '0',

-- voting and ratings
    "rating"         BIGINT UNSIGNED
                                  DEFAULT NULL,
    "voteCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "avgRating"      FLOAT        DEFAULT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,
    "locked"         tinyint      DEFAULT '0',
    "extended"       tinyint      DEFAULT '0'
);
CREATE TABLE "containeraux" (
-- used for certain types of containers to ensure title/type uniqueness
    "title"        VARCHAR(255) NOT NULL REFERENCES "container(title)",
    "type"         INTEGER      NOT NULL REFERENCES "container(type)"
);
CREATE TABLE "extend" (
    "id"             INTEGER      PRIMARY KEY AUTOINCREMENT,
    "title"          VARCHAR(255) NOT NULL,
    "document"       TEXT         NOT NULL,
    "contact"        VARCHAR(255) NOT NULL,

    "dateAdded"      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL
);
CREATE TABLE "extension" (
-- fundamental extension information
    "id"             INTEGER      PRIMARY KEY AUTOINCREMENT,
    "extendID"       INTEGER      NOT NULL REFERENCES "extend(id)",
-- exactly one of the following is non-NULL
    "mediaitemID"    INTEGER      DEFAULT NULL REFERENCES
"mediaitem(id)",
    "containerID"    INTEGER      DEFAULT NULL REFERENCES
"container(id)",

    "keyvalue"       VARCHAR(255) NOT NULL,
    "valvalue"       VARCHAR(255) NOT NULL,

    "dateAdded"      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL
);
CREATE TABLE "mediaitem" (
-- fundamental mediaitem information
    "id"             INTEGER      PRIMARY KEY AUTOINCREMENT,
    "title"          VARCHAR(255) NOT NULL,
-- enumerations
--   0: audio
--   1: image
--   2: video
    "type"           INTEGER      NOT NULL,
    "dateAdded"      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,

-- remote access
    "url"            TEXT         NOT NULL,

-- information about source
    "origin"         TEXT         NOT NULL,
    "path"           TEXT         NOT NULL,
    "removable"      tinyint      DEFAULT '0',

-- identity of the containing object
    "containerID"    INTEGER      NOT NULL     REFERENCES
"container(id)",
    "containerPOS"   UNSIGNED INTEGER
                                  DEFAULT NULL,
    "containerDisc"  UNSIGNED INTEGER
                                  DEFAULT NULL,

-- generic information about the media item
    "mimeType"       VARCHAR(255) NOT NULL,    -- e.g., image/jpeg
    "size"           BIGINT UNSIGNED
                                  NOT NULL,
    "details"        TEXT         DEFAULT NULL,-- lyrics, plot, etc.
    "detailsURI"     TEXT         DEFAULT NULL,-- lyrics, plot, etc.
    "genreID"        INTEGER      DEFAULT NULL REFERENCES
"container(id)",
    "thumbnailID"    INTEGER      DEFAULT NULL REFERENCES
"mediaitem(id)",
    "thumb320ID"     INTEGER      DEFAULT NULL REFERENCES
"mediaitem(id)",
    "releaseYearID"  INTEGER      DEFAULT NULL REFERENCES
"container(id)",

-- non-NULL only for audio/video media items
    "duration"       INTEGER UNSIGNED
                                  DEFAULT NULL,-- in seconds

-- non-NULL only for image/video media items
    "width"          INTEGER UNSIGNED
                                  DEFAULT NULL,
    "height"         INTEGER UNSIGNED
                                  DEFAULT NULL,
    "colorDepth"     INTEGER UNSIGNED
                                  DEFAULT NULL,

-- non-NULL only for audio media items
    "artistID"       INTEGER      DEFAULT NULL REFERENCES
"container(id)",
    "bitRate"        INTEGER UNSIGNED
                                  DEFAULT NULL,
    "sampleRate"     INTEGER UNSIGNED
                                  DEFAULT NULL,
    "channels"       INTEGER UNSIGNED
                                  DEFAULT NULL,
    "vbr"            tinyint      DEFAULT NULL,
    "albumGain"      tinyint      DEFAULT NULL,
    "albumType"      VARCHAR(255) DEFAULT NULL,
    "band"           VARCHAR(255) DEFAULT NULL,
    "bitDepth"       INTEGER UNSIGNED
                                  DEFAULT NULL,
    "beatsPerMinute" INTEGER UNSIGNED
                                  DEFAULT NULL,
    "completeAlbum"  tinyint      DEFAULT NULL,
    "compression"    VARCHAR(255) DEFAULT NULL,
    "intensity"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "mixAlbum"       tinyint      DEFAULT NULL,
    "peakLevel"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "replayGain"     INTEGER UNSIGNED
                                  DEFAULT NULL,

-- non-NULL only for image media items
    "aperture"       INTEGER UNSIGNED
                                  DEFAULT NULL,
    "badPixels"      tinyint      DEFAULT NULL,
    "camera"         VARCHAR(255) DEFAULT NULL,
    "caption"        VARCHAR(255) DEFAULT NULL,
    "flash"          tinyint      DEFAULT NULL,
    "focalLength"    INTEGER UNSIGNED
                                  DEFAULT NULL,
    "isoNumber"      VARCHAR(255) DEFAULT NULL,
    "rotation"       INTEGER UNSIGNED
                                  DEFAULT NULL,
    "shutterSpeed"   INTEGER UNSIGNED
                                  DEFAULT NULL,

-- non-NULL only for video media items
    "mpaaRating"     VARCHAR(5)   DEFAULT NULL, -- one of:
                                                -- G, PG, PG-13, NC-17,
R, or NR
                                                -- historic: G, GP, M,
or X
    "mpaaReasons"    VARCHAR(7)   DEFAULT NULL, -- any of:
                                                -- V, S, L, and/or D
    "program"        VARCHAR(255) DEFAULT NULL,
    "episode"        VARCHAR(255) DEFAULT NULL,

-- voting and ratings
    "rating"         BIGINT UNSIGNED
                                  DEFAULT NULL,
    "voteCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "avgRating"      FLOAT        DEFAULT NULL,

-- ownership, rights, etc.
    "copyright"      TEXT         DEFAULT NULL,

-- finally, housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,
    "locked"         tinyint      DEFAULT '0',
    "extended"       tinyint      DEFAULT '0'
);
CREATE TABLE "tag" (
-- fundamental tag information
    "id"             INTEGER      PRIMARY KEY AUTOINCREMENT,
-- only one of mediaitemID or containerID is non-NULL
-- containerID may be non-NULL, ONLY:
--     IF the parentID's type is "user-defined tag"
--     AND the containerID's type is not "user-defined tag"
--   OR
--    IF the parentID's type is "media folder"
--     AND the containerID's type is also "media folder"
--   OR
--    IF the parentID's type is "music artist"
--     AND the containerID's type is "music album"
    "mediaitemID"    INTEGER      DEFAULT NULL REFERENCES
"mediaitem(id)",
    "containerID"    INTEGER      DEFAULT NULL REFERENCES
"container(id)",
    "parentID"       INTEGER      NOT NULL REFERENCES "container(id)",
    "parentPOS"      UNSIGNED INTEGER
                                  DEFAULT NULL,

    "dateAdded"      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL
);
CREATE TABLE "user" (
-- fundamental userinformation
    "userid"         INTEGER      PRIMARY KEY AUTOINCREMENT

-- other user-specific attributes go here...
);
CREATE TABLE "usercontainer" (
-- fundamental usercontainer information
    "containerID"    INTEGER      NOT NULL REFERENCES "container(id)",
    "userID"         INTEGER      NOT NULL REFERENCES "user(userid)",

-- user-specific container information
    "notes"          TEXT         DEFAULT NULL,-- user-supplied
    "comments"       TEXT         DEFAULT NULL,
    "dateLastPlayed" TIMESTAMP    DEFAULT NULL,
    "lastPlayedPosition" BIGINT UNSIGNED
                                  DEFAULT NULL,-- in
hundredths-of-a-second
    "playCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "dateLastSkipped" TIMESTAMP    DEFAULT NULL,
    "skipCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "rating"         INTEGER      DEFAULT NULL, -- range: 1..5

-- bookmark information
    "parentPOS"      UNSIGNED INTEGER          -- identifies position of
media
                                  DEFAULT NULL,-- item having bookmark
    "bookmark"       BIGINT UNSIGNED
                                  DEFAULT NULL,-- in
hundredths-of-a-second
    "useBookmark"    tinyint      DEFAULT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL
);
CREATE TABLE "usermediaitem" (
-- fundamental usermediaitem information
    "mediaitemID"    INTEGER      NOT NULL REFERENCES "mediaitem(id)",
    "userID"         INTEGER      NOT NULL REFERENCES "user(userid)",

-- user-specific media item information
    "notes"          TEXT         DEFAULT NULL,-- user-supplied
    "comments"       TEXT         DEFAULT NULL,
    "dateLastPlayed" TIMESTAMP    DEFAULT NULL,
    "lastPlayedPosition" BIGINT UNSIGNED
                                  DEFAULT NULL,-- in
hundredths-of-a-second
    "playCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "dateLastSkipped" TIMESTAMP    DEFAULT NULL,
    "skipCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "rating"         INTEGER      DEFAULT NULL, -- range: 1..5

-- non-NULL only for audio/video media items
    "bookmark"       BIGINT UNSIGNED
                                  DEFAULT NULL,-- in
hundredths-of-a-second
    "useBookmark"    tinyint      DEFAULT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL
);
CREATE UNIQUE INDEX "auxid"          ON containeraux(title,type);
CREATE INDEX container_avgRating     ON container(avgRating);
CREATE INDEX container_dateAdded     ON container(dateAdded);
CREATE INDEX container_id ON container(id);
CREATE INDEX container_title         ON container(title);
CREATE INDEX container_type          ON container(type);
CREATE INDEX extend_contact          ON extend(contact);
CREATE INDEX extend_title            ON extend(title);
CREATE INDEX extension_containerID   ON extension(containerID);
CREATE INDEX extension_extendID      ON extension(extendID);
CREATE INDEX extension_keyvalue      ON extension(keyvalue);
CREATE INDEX extension_mediaitemID   ON extension(mediaitemID);
CREATE INDEX mediaitem_artistID      ON mediaitem(artistID);
CREATE INDEX mediaitem_avgRating     ON mediaitem(avgRating);
CREATE INDEX mediaitem_containerID   ON mediaitem(containerID);
CREATE INDEX mediaitem_dateAdded     ON mediaitem(dateAdded);
CREATE INDEX mediaitem_genreID       ON mediaitem(genreID);
CREATE INDEX mediaitem_mpaaRating    ON mediaitem(mpaaRating);
CREATE INDEX mediaitem_releaseYearID ON mediaitem(releaseYearID);
CREATE INDEX mediaitem_thumb320ID    ON mediaitem(thumb320ID);
CREATE INDEX mediaitem_thumbnailID   ON mediaitem(thumbnailID);
CREATE INDEX mediaitem_title         ON mediaitem(title);
CREATE INDEX mediaitem_type          ON mediaitem(type);
CREATE INDEX tag_containerID         ON tag(containerID);
CREATE INDEX tag_mediaitemID         ON tag(mediaitemID);
CREATE INDEX tag_parentID            ON tag(parentID);
CREATE UNIQUE INDEX "ucid"           ON
usercontainer(containerID,userID);
CREATE UNIQUE INDEX "ulid"           ON
usermediaitem(mediaitemID,userID);
CREATE INDEX usercontainer_containerID ON usercontainer(containerID);
CREATE INDEX usercontainer_userid    ON usercontainer(userid);
CREATE INDEX usermediaitem_mediaitemID ON usermediaitem(mediaitemID);
CREATE INDEX usermediaitem_userid    ON usermediaitem(userid);

-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Dennis Cote
Sent: Wednesday, April 09, 2008 11:25 AM
To: General Discussion of SQLite Database
Subject: Re: [sqlite] Left Join help

Andy Smith wrote:
> I have quiet a few queries similar to this doing multiple Left Joins
and
> they  run extremely slow > 6 secs. Is there a better way to be writing
> the below query for sqlite.
> 

Andy,

You didn't show your table and index definitions, so it's hard to be 
sure about what would be best.

The following trace shows what I think your tables should look like, and

a couple of indexes that will help for a slightly rearranged version of 
your query. The query plan uses the indexes to locate the subset of the 
records with type=0, then checks their title, next it uses the other 
index to find the matching records and checks that their type=1. These 
records should lead directly to the required container records using the

primary key on that table. I would suspect this is reasonably fast. Let 
me know if it helps.

HTH
Dennis Cote

SQLite version 3.5.7
Enter ".help" for instructions
sqlite>
sqlite> create table container (
    ...>     id integer primary key,
    ...>     title text
    ...> );
sqlite>
sqlite> create table mediaitem (
    ...>     id integer primary key,
    ...>     title text,
    ...>     type integer,
    ...>     containerID integer references container,
    ...>     genreID integer references container,
    ...>     thumbnailID integer references container,
    ...>     releaseYearID integer references container,
    ...>     artistID integer references container,
    ...>     dateAdded,
    ...>     url,
    ...>     path,
    ...>     mimeType,
    ...>     width,
    ...>     height
    ...> );
sqlite>
sqlite> create index media_type on mediaitem(type);
sqlite> create index media_container on mediaitem(containerID);
sqlite>
sqlite> explain query plan
    ...> SELECT
    ...>     a.id,
    ...>     a.title,
    ...>     a.type,
    ...>     a.dateAdded,
    ...>     a.url,
    ...>     a.path,
    ...>     a.containerID,
    ...>     a.mimeType,
    ...>     a.width,
    ...>     a.height,
    ...>     a.genreID,
    ...>     a.thumbnailID,
    ...>     a.releaseYearID,
    ...>     a.artistID,
    ...>     w.title AS containerName,
    ...>     x.title AS genreName,
    ...>     y.title AS releaseYearName,
    ...>     z.title AS artistName
    ...> FROM mediaitem AS b
    ...> LEFT JOIN mediaitem AS a ON b.containerID=a.containerID
    ...> LEFT JOIN container AS w ON w.id=a.containerID
    ...> LEFT JOIN container AS x ON x.id=a.genreID
    ...> LEFT JOIN container AS y ON y.id=a.releaseYearID
    ...> LEFT JOIN container AS z ON z.id=a.artistID
    ...> WHERE b.title LIKE 'Opus%' ESCAPE '\'
    ...>     AND b.type=0
    ...>     AND a.type=1
    ...> ORDER BY a.title, a.id
    ...> LIMIT 0,9;
0|0|TABLE mediaitem AS b WITH INDEX media_type
1|1|TABLE mediaitem AS a WITH INDEX media_container
2|2|TABLE container AS w USING PRIMARY KEY
3|3|TABLE container AS x USING PRIMARY KEY
4|4|TABLE container AS y USING PRIMARY KEY
5|5|TABLE container AS z USING PRIMARY KEY
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users



This message is confidential to Prodea Systems, Inc unless otherwise indicated 
or apparent from its nature. This message is directed to the intended recipient 
only, who may be readily determined by the sender of this message and its 
contents. If the reader of this message is not the intended recipient, or an 
employee or agent responsible for delivering this message to the intended 
recipient:(a)any dissemination or copying of this message is strictly 
prohibited; and(b)immediately notify the sender by return message and destroy 
any copies of this message in any form(electronic, paper or otherwise) that you 
have.The delivery of this message and its information is neither intended to be 
nor constitutes a disclosure or waiver of any trade secrets, intellectual 
property, attorney work product, or attorney-client communications. The 
authority of the individual sending this message to legally bind Prodea Systems 
 
is neither apparent nor implied,and must be independently verified.
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Andy Smith <[EMAIL PROTECTED]> wrote: I have to get this down to < 1 sec. I 
have 50 queries that are all
formatted similar.  We have created another schema where the container
is split into smaller tables which might help in speeding this up.  From
what I see the Left joins are killing the speed.

Here is what I am seeing when running explain query plan:

sqlite> explain query plan SELECT a.id, a.title, a.type, a.dateAdded,
a.url, a.path, a.containerID, a.mimeType, a.width, a.height, a.genreID,
a.thumbnailID, a.releaseYearID, a.artistID, w.title AS containerName,
x.title AS genreName, y.title AS releaseYearName, z.title AS artistName
FROM mediaitem AS a LEFT JOIN mediaitem AS b ON
b.containerID=a.containerID LEFT JOIN container AS w ON
w.id=a.containerID LEFT JOIN container AS x ON x.id=a.genreID LEFT JOIN
container AS y ON y.id=a.releaseYearID LEFT JOIN container AS z ON
z.id=a.artistID WHERE a.type=1 AND b.type=0 AND b.title LIKE 'Opus%'
ESCAPE '\' ORDER BY a.title, a.id LIMIT 0,9;

0|0|TABLE mediaitem AS a WITH INDEX mediaitem_title ORDER BY
1|1|TABLE mediaitem AS b WITH INDEX mediaitem_containerID
2|2|TABLE container AS w USING PRIMARY KEY
3|3|TABLE container AS x USING PRIMARY KEY
4|4|TABLE container AS y USING PRIMARY KEY
5|5|TABLE container AS z USING PRIMARY KEY

Schema:

sqlite> .schema
CREATE TABLE "container" (
-- fundamental container information
    "id"           INTEGER      PRIMARY KEY AUTOINCREMENT,
    "title"        VARCHAR(255) NOT NULL,
-- enumerations
--   10: music album
--   11: music artist
--   12: music genre
--   13: music composer
--   14: music conductor
--   15: release year
--   16: photo roll
--   17: photo album / slide show
--   18: events
--   19: keyword
--   20: people
--   21: places
--   22: user-defined tag
--   23: playlist
--   24: video season
--   25: video series
--   26: channel
--   27: director
--   28: actor
--   29: producer
--   30: audio series
--   31: media folder

    "type"           INTEGER      NOT NULL,
    "dateAdded"      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,
    "dateCreated"    TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,

-- generic information about the media container
    "details"        TEXT         DEFAULT NULL,-- lyrics, plot, etc.
    "detailsURI"     TEXT         DEFAULT NULL,-- lyrics, plot, etc.

-- non-NULL only for slideshows and playlists
    "duration"       INTEGER UNSIGNED
                                  DEFAULT NULL,-- in seconds
    "transition"     tinyint      DEFAULT '0', -- 0: no effect
                                               -- 1: fade in/out

-- non-NULL only for media folders
    "upnpShared"     tinyint      DEFAULT '0',
    "parentalLocked" tinyint      DEFAULT '0',

-- voting and ratings
    "rating"         BIGINT UNSIGNED
                                  DEFAULT NULL,
    "voteCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "avgRating"      FLOAT        DEFAULT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,
    "locked"         tinyint      DEFAULT '0',
    "extended"       tinyint      DEFAULT '0'
);
CREATE TABLE "containeraux" (
-- used for certain types of containers to ensure title/type uniqueness
    "title"        VARCHAR(255) NOT NULL REFERENCES "container(title)",
    "type"         INTEGER      NOT NULL REFERENCES "container(type)"
);
CREATE TABLE "extend" (
    "id"             INTEGER      PRIMARY KEY AUTOINCREMENT,
    "title"          VARCHAR(255) NOT NULL,
    "document"       TEXT         NOT NULL,
    "contact"        VARCHAR(255) NOT NULL,

    "dateAdded"      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL
);
CREATE TABLE "extension" (
-- fundamental extension information
    "id"             INTEGER      PRIMARY KEY AUTOINCREMENT,
    "extendID"       INTEGER      NOT NULL REFERENCES "extend(id)",
-- exactly one of the following is non-NULL
    "mediaitemID"    INTEGER      DEFAULT NULL REFERENCES
"mediaitem(id)",
    "containerID"    INTEGER      DEFAULT NULL REFERENCES
"container(id)",

    "keyvalue"       VARCHAR(255) NOT NULL,
    "valvalue"       VARCHAR(255) NOT NULL,

    "dateAdded"      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL
);
CREATE TABLE "mediaitem" (
-- fundamental mediaitem information
    "id"             INTEGER      PRIMARY KEY AUTOINCREMENT,
    "title"          VARCHAR(255) NOT NULL,
-- enumerations
--   0: audio
--   1: image
--   2: video
    "type"           INTEGER      NOT NULL,
    "dateAdded"      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,

-- remote access
    "url"            TEXT         NOT NULL,

-- information about source
    "origin"         TEXT         NOT NULL,
    "path"           TEXT         NOT NULL,
    "removable"      tinyint      DEFAULT '0',

-- identity of the containing object
    "containerID"    INTEGER      NOT NULL     REFERENCES
"container(id)",
    "containerPOS"   UNSIGNED INTEGER
                                  DEFAULT NULL,
    "containerDisc"  UNSIGNED INTEGER
                                  DEFAULT NULL,

-- generic information about the media item
    "mimeType"       VARCHAR(255) NOT NULL,    -- e.g., image/jpeg
    "size"           BIGINT UNSIGNED
                                  NOT NULL,
    "details"        TEXT         DEFAULT NULL,-- lyrics, plot, etc.
    "detailsURI"     TEXT         DEFAULT NULL,-- lyrics, plot, etc.
    "genreID"        INTEGER      DEFAULT NULL REFERENCES
"container(id)",
    "thumbnailID"    INTEGER      DEFAULT NULL REFERENCES
"mediaitem(id)",
    "thumb320ID"     INTEGER      DEFAULT NULL REFERENCES
"mediaitem(id)",
    "releaseYearID"  INTEGER      DEFAULT NULL REFERENCES
"container(id)",

-- non-NULL only for audio/video media items
    "duration"       INTEGER UNSIGNED
                                  DEFAULT NULL,-- in seconds

-- non-NULL only for image/video media items
    "width"          INTEGER UNSIGNED
                                  DEFAULT NULL,
    "height"         INTEGER UNSIGNED
                                  DEFAULT NULL,
    "colorDepth"     INTEGER UNSIGNED
                                  DEFAULT NULL,

-- non-NULL only for audio media items
    "artistID"       INTEGER      DEFAULT NULL REFERENCES
"container(id)",
    "bitRate"        INTEGER UNSIGNED
                                  DEFAULT NULL,
    "sampleRate"     INTEGER UNSIGNED
                                  DEFAULT NULL,
    "channels"       INTEGER UNSIGNED
                                  DEFAULT NULL,
    "vbr"            tinyint      DEFAULT NULL,
    "albumGain"      tinyint      DEFAULT NULL,
    "albumType"      VARCHAR(255) DEFAULT NULL,
    "band"           VARCHAR(255) DEFAULT NULL,
    "bitDepth"       INTEGER UNSIGNED
                                  DEFAULT NULL,
    "beatsPerMinute" INTEGER UNSIGNED
                                  DEFAULT NULL,
    "completeAlbum"  tinyint      DEFAULT NULL,
    "compression"    VARCHAR(255) DEFAULT NULL,
    "intensity"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "mixAlbum"       tinyint      DEFAULT NULL,
    "peakLevel"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "replayGain"     INTEGER UNSIGNED
                                  DEFAULT NULL,

-- non-NULL only for image media items
    "aperture"       INTEGER UNSIGNED
                                  DEFAULT NULL,
    "badPixels"      tinyint      DEFAULT NULL,
    "camera"         VARCHAR(255) DEFAULT NULL,
    "caption"        VARCHAR(255) DEFAULT NULL,
    "flash"          tinyint      DEFAULT NULL,
    "focalLength"    INTEGER UNSIGNED
                                  DEFAULT NULL,
    "isoNumber"      VARCHAR(255) DEFAULT NULL,
    "rotation"       INTEGER UNSIGNED
                                  DEFAULT NULL,
    "shutterSpeed"   INTEGER UNSIGNED
                                  DEFAULT NULL,

-- non-NULL only for video media items
    "mpaaRating"     VARCHAR(5)   DEFAULT NULL, -- one of:
                                                -- G, PG, PG-13, NC-17,
R, or NR
                                                -- historic: G, GP, M,
or X
    "mpaaReasons"    VARCHAR(7)   DEFAULT NULL, -- any of:
                                                -- V, S, L, and/or D
    "program"        VARCHAR(255) DEFAULT NULL,
    "episode"        VARCHAR(255) DEFAULT NULL,

-- voting and ratings
    "rating"         BIGINT UNSIGNED
                                  DEFAULT NULL,
    "voteCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "avgRating"      FLOAT        DEFAULT NULL,

-- ownership, rights, etc.
    "copyright"      TEXT         DEFAULT NULL,

-- finally, housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,
    "locked"         tinyint      DEFAULT '0',
    "extended"       tinyint      DEFAULT '0'
);
CREATE TABLE "tag" (
-- fundamental tag information
    "id"             INTEGER      PRIMARY KEY AUTOINCREMENT,
-- only one of mediaitemID or containerID is non-NULL
-- containerID may be non-NULL, ONLY:
--     IF the parentID's type is "user-defined tag"
--     AND the containerID's type is not "user-defined tag"
--   OR
--    IF the parentID's type is "media folder"
--     AND the containerID's type is also "media folder"
--   OR
--    IF the parentID's type is "music artist"
--     AND the containerID's type is "music album"
    "mediaitemID"    INTEGER      DEFAULT NULL REFERENCES
"mediaitem(id)",
    "containerID"    INTEGER      DEFAULT NULL REFERENCES
"container(id)",
    "parentID"       INTEGER      NOT NULL REFERENCES "container(id)",
    "parentPOS"      UNSIGNED INTEGER
                                  DEFAULT NULL,

    "dateAdded"      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL
);
CREATE TABLE "user" (
-- fundamental userinformation
    "userid"         INTEGER      PRIMARY KEY AUTOINCREMENT

-- other user-specific attributes go here...
);
CREATE TABLE "usercontainer" (
-- fundamental usercontainer information
    "containerID"    INTEGER      NOT NULL REFERENCES "container(id)",
    "userID"         INTEGER      NOT NULL REFERENCES "user(userid)",

-- user-specific container information
    "notes"          TEXT         DEFAULT NULL,-- user-supplied
    "comments"       TEXT         DEFAULT NULL,
    "dateLastPlayed" TIMESTAMP    DEFAULT NULL,
    "lastPlayedPosition" BIGINT UNSIGNED
                                  DEFAULT NULL,-- in
hundredths-of-a-second
    "playCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "dateLastSkipped" TIMESTAMP    DEFAULT NULL,
    "skipCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "rating"         INTEGER      DEFAULT NULL, -- range: 1..5

-- bookmark information
    "parentPOS"      UNSIGNED INTEGER          -- identifies position of
media
                                  DEFAULT NULL,-- item having bookmark
    "bookmark"       BIGINT UNSIGNED
                                  DEFAULT NULL,-- in
hundredths-of-a-second
    "useBookmark"    tinyint      DEFAULT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL
);
CREATE TABLE "usermediaitem" (
-- fundamental usermediaitem information
    "mediaitemID"    INTEGER      NOT NULL REFERENCES "mediaitem(id)",
    "userID"         INTEGER      NOT NULL REFERENCES "user(userid)",

-- user-specific media item information
    "notes"          TEXT         DEFAULT NULL,-- user-supplied
    "comments"       TEXT         DEFAULT NULL,
    "dateLastPlayed" TIMESTAMP    DEFAULT NULL,
    "lastPlayedPosition" BIGINT UNSIGNED
                                  DEFAULT NULL,-- in
hundredths-of-a-second
    "playCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "dateLastSkipped" TIMESTAMP    DEFAULT NULL,
    "skipCount"      INTEGER UNSIGNED
                                  DEFAULT NULL,
    "rating"         INTEGER      DEFAULT NULL, -- range: 1..5

-- non-NULL only for audio/video media items
    "bookmark"       BIGINT UNSIGNED
                                  DEFAULT NULL,-- in
hundredths-of-a-second
    "useBookmark"    tinyint      DEFAULT NULL,

-- housekeeping...
    "dateModified"   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP
                                  NOT NULL
);
CREATE UNIQUE INDEX "auxid"          ON containeraux(title,type);
CREATE INDEX container_avgRating     ON container(avgRating);
CREATE INDEX container_dateAdded     ON container(dateAdded);
CREATE INDEX container_id ON container(id);
CREATE INDEX container_title         ON container(title);
CREATE INDEX container_type          ON container(type);
CREATE INDEX extend_contact          ON extend(contact);
CREATE INDEX extend_title            ON extend(title);
CREATE INDEX extension_containerID   ON extension(containerID);
CREATE INDEX extension_extendID      ON extension(extendID);
CREATE INDEX extension_keyvalue      ON extension(keyvalue);
CREATE INDEX extension_mediaitemID   ON extension(mediaitemID);
CREATE INDEX mediaitem_artistID      ON mediaitem(artistID);
CREATE INDEX mediaitem_avgRating     ON mediaitem(avgRating);
CREATE INDEX mediaitem_containerID   ON mediaitem(containerID);
CREATE INDEX mediaitem_dateAdded     ON mediaitem(dateAdded);
CREATE INDEX mediaitem_genreID       ON mediaitem(genreID);
CREATE INDEX mediaitem_mpaaRating    ON mediaitem(mpaaRating);
CREATE INDEX mediaitem_releaseYearID ON mediaitem(releaseYearID);
CREATE INDEX mediaitem_thumb320ID    ON mediaitem(thumb320ID);
CREATE INDEX mediaitem_thumbnailID   ON mediaitem(thumbnailID);
CREATE INDEX mediaitem_title         ON mediaitem(title);
CREATE INDEX mediaitem_type          ON mediaitem(type);
CREATE INDEX tag_containerID         ON tag(containerID);
CREATE INDEX tag_mediaitemID         ON tag(mediaitemID);
CREATE INDEX tag_parentID            ON tag(parentID);
CREATE UNIQUE INDEX "ucid"           ON
usercontainer(containerID,userID);
CREATE UNIQUE INDEX "ulid"           ON
usermediaitem(mediaitemID,userID);
CREATE INDEX usercontainer_containerID ON usercontainer(containerID);
CREATE INDEX usercontainer_userid    ON usercontainer(userid);
CREATE INDEX usermediaitem_mediaitemID ON usermediaitem(mediaitemID);
CREATE INDEX usermediaitem_userid    ON usermediaitem(userid);

-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Dennis Cote
Sent: Wednesday, April 09, 2008 11:25 AM
To: General Discussion of SQLite Database
Subject: Re: [sqlite] Left Join help

Andy Smith wrote:
> I have quiet a few queries similar to this doing multiple Left Joins
and
> they  run extremely slow > 6 secs. Is there a better way to be writing
> the below query for sqlite.
> 

Andy,

You didn't show your table and index definitions, so it's hard to be 
sure about what would be best.

The following trace shows what I think your tables should look like, and

a couple of indexes that will help for a slightly rearranged version of 
your query. The query plan uses the indexes to locate the subset of the 
records with type=0, then checks their title, next it uses the other 
index to find the matching records and checks that their type=1. These 
records should lead directly to the required container records using the

primary key on that table. I would suspect this is reasonably fast. Let 
me know if it helps.

HTH
Dennis Cote

SQLite version 3.5.7
Enter ".help" for instructions
sqlite>
sqlite> create table container (
    ...>     id integer primary key,
    ...>     title text
    ...> );
sqlite>
sqlite> create table mediaitem (
    ...>     id integer primary key,
    ...>     title text,
    ...>     type integer,
    ...>     containerID integer references container,
    ...>     genreID integer references container,
    ...>     thumbnailID integer references container,
    ...>     releaseYearID integer references container,
    ...>     artistID integer references container,
    ...>     dateAdded,
    ...>     url,
    ...>     path,
    ...>     mimeType,
    ...>     width,
    ...>     height
    ...> );
sqlite>
sqlite> create index media_type on mediaitem(type);
sqlite> create index media_container on mediaitem(containerID);
sqlite>
sqlite> explain query plan
    ...> SELECT
    ...>     a.id,
    ...>     a.title,
    ...>     a.type,
    ...>     a.dateAdded,
    ...>     a.url,
    ...>     a.path,
    ...>     a.containerID,
    ...>     a.mimeType,
    ...>     a.width,
    ...>     a.height,
    ...>     a.genreID,
    ...>     a.thumbnailID,
    ...>     a.releaseYearID,
    ...>     a.artistID,
    ...>     w.title AS containerName,
    ...>     x.title AS genreName,
    ...>     y.title AS releaseYearName,
    ...>     z.title AS artistName
    ...> FROM mediaitem AS b
    ...> LEFT JOIN mediaitem AS a ON b.containerID=a.containerID
    ...> LEFT JOIN container AS w ON w.id=a.containerID
    ...> LEFT JOIN container AS x ON x.id=a.genreID
    ...> LEFT JOIN container AS y ON y.id=a.releaseYearID
    ...> LEFT JOIN container AS z ON z.id=a.artistID
    ...> WHERE b.title LIKE 'Opus%' ESCAPE '\'
    ...>     AND b.type=0
    ...>     AND a.type=1
    ...> ORDER BY a.title, a.id
    ...> LIMIT 0,9;
0|0|TABLE mediaitem AS b WITH INDEX media_type
1|1|TABLE mediaitem AS a WITH INDEX media_container
2|2|TABLE container AS w USING PRIMARY KEY
3|3|TABLE container AS x USING PRIMARY KEY
4|4|TABLE container AS y USING PRIMARY KEY
5|5|TABLE container AS z USING PRIMARY KEY
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users



This message is confidential to Prodea Systems, Inc unless otherwise indicated 
or apparent from its nature. This message is directed to the intended recipient 
only, who may be readily determined by the sender of this message and its 
contents. If the reader of this message is not the intended recipient, or an 
employee or agent responsible for delivering this message to the intended 
recipient:(a)any dissemination or copying of this message is strictly 
prohibited; and(b)immediately notify the sender by return message and destroy 
any copies of this message in any form(electronic, paper or otherwise) that you 
have.The delivery of this message and its information is neither intended to be 
nor constitutes a disclosure or waiver of any trade secrets, intellectual 
property, attorney work product, or attorney-client communications. The 
authority of the individual sending this message to legally bind Prodea Systems 
 
is neither apparent nor implied,and must be independently verified.
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to