Have you tried removing all the useless brackets that Micro$oft adds to the query? I don't know if the parser strips them out automagically or if they are used as join order hints. You are better off letting the optimizer optimize unless you really really want to force a specific order. While some SQL databases ignore such tomfoolery, others do not. I do not know off-hand whether SQLite ignores tomfoolery or not. I just habitually remove them.
SELECT Objects.Object_ID, Object_TextTables.Lower_Limit, Object_TextTables.Upper_Limit, Object_TextTables.TextTable_ID, DTC_Statuses.DTC_Status_ID, DTC_Statuses.Env_Data, DTC_Statuses.Env_Offset, DTC_Statuses.DTCs_Follow, DTC_Statuses.Upper_Limit, DTC_Statuses.Lower_Limit, DTC_Statuses.Physical_Value, Object_Transactions.Element_Offset, Equation_Types.Equation_Type, Equations.BitMask, Equations.ByteSpecific, Equations.ObjectSpecific, Equations.InternalEncoder, Equations.Equation, Objects.Object_Size, Objects.Signed, Objects.Visible, Object_Types.Object_Type, DisplayFormats.DisplayFormat FROM Objects INNER JOIN DTC_Statuses ON Objects.Object_ID=DTC_Statuses.Object_ID INNER JOIN Object_TextTables ON Objects.Object_ID=Object_TextTables.Object_ID INNER JOIN Object_Transactions ON Objects.Object_ID=Object_Transactions.Object_ID INNER JOIN Equations ON Object_Transactions.Equation_ID=Equations.Equation_ID INNER JOIN Equation_Types ON Object_Transactions.Equation_Type_ID=Equation_Types.Equation_Type_ID INNER JOIN Object_Types ON Objects.Object_Type_ID=Object_Types.Object_Type_ID INNER JOIN DisplayFormats ON Objects.DisplayFormat_ID=DisplayFormats.DisplayFormat_ID WHERE Object_Types.Object_Type='DTC'; I presume that the optimizer will then actually devolve this into the optimizable form. Some SQL parsers do, and some do not. Personally, except for extremely trivially joins (or where JOIN syntax must be used for OUTER joins) I always use the less semantically loaded form of speech thus, to ensure that the parsing order does not influence the optimizer. Technically, if a different query plan is obtained when using the M$ bracketed form, the above form, and the below form, the optimizer is using the brackets and JOIN syntax ordering to provide hints -- which may not result in the optimum query plan unless you know what you are doing (and what the optimizer in question will do when parsing the input semantics) SELECT Objects.Object_ID, Object_TextTables.Lower_Limit, Object_TextTables.Upper_Limit, Object_TextTables.TextTable_ID, DTC_Statuses.DTC_Status_ID, DTC_Statuses.Env_Data, DTC_Statuses.Env_Offset, DTC_Statuses.DTCs_Follow, DTC_Statuses.Upper_Limit, DTC_Statuses.Lower_Limit, DTC_Statuses.Physical_Value, Object_Transactions.Element_Offset, Equation_Types.Equation_Type, Equations.BitMask, Equations.ByteSpecific, Equations.ObjectSpecific, Equations.InternalEncoder, Equations.Equation, Objects.Object_Size, Objects.Signed, Objects.Visible, Object_Types.Object_Type, DisplayFormats.DisplayFormat FROM Objects, DTC_Statuses, Object_TextTables, Object_Transactions, Equations, Equation_Types, Object_Types, DisplayFormats, WHERE Objects.Object_ID=DTC_Statuses.Object_ID AND Objects.Object_ID=Object_TextTables.Object_ID AND Objects.Object_ID=Object_Transactions.Object_ID AND Object_Transactions.Equation_ID=Equations.Equation_ID AND Object_Transactions.Equation_Type_ID=Equation_Types.Equation_Type_ID AND Objects.Object_Type_ID=Object_Types.Object_Type_ID AND Objects.DisplayFormat_ID=DisplayFormats.DisplayFormat_ID AND Object_Types.Object_Type='DTC'; And then properly handle transitive equalities so that it can generate the best query plan, assuming that every column mentioned as a conditional column is included in an appropriate index (appropriately set as unique, if it is unique), and that tables which require more than one column to be indexed have *all* the referenced columns included in the index. If a table has two mentioned columns you should create both indexes (mutatis mutandis for more than two columns)). Ensure unique columns are actually constrained unique in the table definition (or by a manually created unique index, which is the same thing). Then do an analyze and look at the generated output from EXPLAIN QUERY PLAN which will tell you the optimum join order so you can eliminate unneeded indexes and extend the indexes used to be covering indexes if you really want the maximum performance. Are you using a version of SQLite3 that supports transitive conditions (what version are you using)? If not, you should specify them in the query, eg: WHERE A=B and B=C Should be stated as WHERE A=B and B=C and A=C Assuming that Object_Types.Object_Type='DTC' selects one row, that should likely be selected as the outer query loop since the optimizer should be seeking to minimize selection and using indexes to SEARCH inner tables using a minimum selection product at each step (that is what the row count in the EXPLAIN QUERY PLAN indicates -- it indicates selectivity of at that step, not the number of rows in the table -- a SCAN of a table containing a billion rows with the annotation (~1 ROW) means that after scanning the all the rows, the constraints to that point are expected to match ~1 row out of the billion scanned [needless to say this is very slow] -- a SEARCH resulting in (~1 row) means that the optimizer expects to be able to use an index to select one row from the table (lightening fast) -- (~1000000 rows) means that there is no information to determine how many rows will be selected and this step might or does devolve to a cross join which may result in a huge number of candidates goi ng into the next loop). --- () ascii ribbon campaign against html e-mail /\ www.asciiribbon.org > -----Original Message----- > From: sqlite-users-boun...@sqlite.org [mailto:sqlite-users- > boun...@sqlite.org] On Behalf Of ven...@intouchmi.com > Sent: Monday, 15 April, 2013 15:20 > To: sqlite-users@sqlite.org > Subject: Re: [sqlite] Help speed up query > > SQLite was much slower on many queries AFTER analyze was executed. > > here are the referenced tables, # of rows, primary key, and additional > indexes: > Objects = 5495 rows, Primary key=Object_ID, other indexes on Address_ID, > Dimension_ID, DisplayFormat_ID, Limit_ID, and Object_ID; > DTC_Statuses = 5234 rows, Primary key=DTC_Status_ID, other index on > Object_ID; > Object_TextTables = 15718 rows, other indexes on Object_ID and > TextTable_ID; > Object_Transactions = 5747 rows, Primary key=Object_Transaction_ID, other > indexes on Equation_ID, Object_ID, Transaction_ID; > Equations = 43 rows, Primary key=Equation_ID; > Equation_Types = 10 rows, Primary key=Equation_Type_ID; > Object_Types = 5 rows, Primary key=Object_Type_ID; > DisplayFormats = 7 rows, Primary key=DisplayFormat_ID. > > I'm not sure where it is getting 1000000 rows! > > Vance > > on Apr 15, 2013, Simon Slavin <slav...@bigfraud.org> wrote: > > > > > >On 15 Apr 2013, at 9:47pm, ven...@intouchmi.com wrote: > > > >> The integrity check came back with OK. > > > >Good. > > > >> My software was not locked up totally. It did finally come back. For > some reason > >executing analyze slow other queries way down. > > > >I am surprised by anyone reporting that ANALYZE has substancially slowed > down any > >operation. Please excuse me because I have trouble understanding English > sometimes. > > Can you verify for us: > > > >A) The slow-down you're talking about. Are you saying that other > operations ran slowly > >while you were doing ANALYZE, or that the SELECTs ran more slowly after > the ANALYZE > >than they did before it ? > > > >B) Reading the results of the EXPLAIN QUERY PLAN after the ANALYZE, you > should see > >approximate row counts like > > > >> 0|5|3|SCAN TABLE DisplayFormats (~7 rows) > > > >This means that the table DisplayFormats has about 7 rows. If you take > this as meaning > >that it has between 1 and 70 rows, are these rowcounts correct as far as > you know, > >or has it completely miscounted a table which actually has thousands of > rows as having > >just 1 row ? > > > >C) Are these EXPLAIN QUERY PLANs you're posting all for the same SELECT > statement > >or are you switching from one to another ? > > > >Also I see in your latest EQP > > > >> 0|1|1|SCAN TABLE DTC_Statuses (~1000000 rows) > > > >Obviously, scanning a million rows is something you want to avoid. Have > you created > >an appropriate index ? > > > >Simon > >_______________________________________________ > >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 _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users