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

Reply via email to