Symbian3/SDK/Source/GUID-2A2920E0-5D40-5358-BC0C-8572CEFE078C.dita
author Dominic Pinkman <Dominic.Pinkman@Nokia.com>
Thu, 21 Jan 2010 18:18:20 +0000
changeset 0 89d6a7a84779
permissions -rw-r--r--
Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
     1
<?xml version="1.0" encoding="utf-8"?>
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
     2
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
     3
<!-- This component and the accompanying materials are made available under the terms of the License 
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
     4
"Eclipse Public License v1.0" which accompanies this distribution, 
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
     5
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
     6
<!-- Initial Contributors:
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
     7
    Nokia Corporation - initial contribution.
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
     8
Contributors: 
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
     9
-->
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    10
<!DOCTYPE concept
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    11
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    12
<concept xml:lang="en" id="GUID-2A2920E0-5D40-5358-BC0C-8572CEFE078C"><title>SQL Expressions</title><prolog><metadata><keywords/></metadata></prolog><conbody><p>This document explains how the optimizer changes expressions. </p> <section><title>Introduction</title> <p>The way an expression is written really does matter. When written well expressions not only clearly state what is intended but they can also improve the performance of the SQL engine significantly. This document provides several tips designed to help you improve your SQL expressions. </p> <p><b>Intended audience:</b> </p> <p>This document is intended to be used by Symbian OS licensees and third party application developers. </p> </section> <section id="GUID-5E95EACE-CC82-55CD-BF88-C8C92A3222E8"><title>Expression Rewriting Optimizations</title> <p>In an earlier section we described how the optimizer would only make use of an index if one of the columns being indexed occurred on one side of certain equality and comparison operators (“<b>=</b> ”, “<b>IN</b> ”, “<b>&lt;</b> ”, “<b>&gt;</b> ”, “<b>&lt;=</b> ”, “<b>&gt;=</b> ”, and sometimes “<b>IS NULL</b> ”). </p> <p>While this is technically true, prior to the stage of the analysis where the optimizer is looking for these kinds of expressions, it may have first modified the <codeph>WHERE</codeph> clause (or the <codeph>ON</codeph> or <codeph>HAVING</codeph> clause) from what was originally entered by the programmer. </p> <p>The next few paragraphs will describe some of these rewriting rules. </p> <p>The query optimizer always rewrites the <codeph>BETWEEN</codeph> operator as a pair of inequalities. So, for example, if the input SQL is this: </p> <codeblock id="GUID-B864D593-8201-5A83-B8CF-55A4A1B8F42F" xml:space="preserve">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    13
SELECT * FROM demo324 WHERE x BETWEEN 7 AND 23;
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    14
</codeblock> <p>What the query optimizer ultimately sees is this: </p> <codeblock id="GUID-CC868858-4B31-5626-A85D-78816D033E69" xml:space="preserve">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    15
SELECT * FROM demo324 WHERE x&gt;=7 AND x&lt;=23;
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    16
</codeblock> <p>In this revised form, the optimizer might be able to use an index on the “x” column to speed the operation of the query. </p> <p>Another rewriting rule is that a disjunction of two or more equality tests against the same column is changed into a single IN operator. So if you write: </p> <codeblock id="GUID-AC72BB25-5BC4-520A-A93E-F8BC9D57A437" xml:space="preserve">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    17
SELECT * FROM demo324 WHERE x=7 OR x=23 OR x=47;
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    18
</codeblock> <p>The WHERE clause will be rewritten into the following form: </p> <codeblock id="GUID-03269149-6080-5039-8817-A2A2A58195D2" xml:space="preserve">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    19
SELECT * FROM demo324 WHERE x IN (7,23,47);
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    20
</codeblock> <p>The original format was not a candidate for use of indexes. But after the disjunction is converted into a single IN operator the usual index processing logic applies and the query can be made much faster. </p> <p>In order for this rewriting rule to be applied, however, all terms of the disjunction must be equality comparisons against the same column. It will not work to have a disjunction involving two or more columns or involving expressions. So, for instance, the following statements will not be optimized: </p> <codeblock id="GUID-2D2F87A3-BD6F-5849-819F-BA0226E4E215" xml:space="preserve">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    21
SELECT * FROM demo324 WHERE x=7 OR y=23;
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    22
SELECT * FROM demo324 WHERE x=7 OR +x=23;
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    23
</codeblock> </section> <section id="GUID-4A75E712-CCF5-568A-894E-2684BA7A9D79"><title> Put Constant Subexpressions inside Subqueries</title> <p>The query parser and compiler in SQLite are designed to be small, fast, and lean. A consequence of this design is that SQLite does not do much in the way of constant folding or common subexpression elimination. SQLite evaluates SQL expressions mostly as written. </p> <p>One way to work around the lack of constant folding in SQLite is to enclose constant subexpressions within a subquery. SQLite does optimize constant subqueries – it evaluates them once, remembers the result, and then reuses that result repeatedly. </p> <p>An example will help clarify how this works. Suppose you have a table that contains a timestamp recorded as the fractional julian day number: </p> <codeblock id="GUID-0A40E590-A590-5AE2-9BC3-9EE627F92207" xml:space="preserve">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    24
CREATE TABLE demo325(tm DATE, data BLOB);
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    25
</codeblock> <p>A query against this table to find all entries after November 8, 2006 might look like the following: </p> <codeblock id="GUID-89C0CA35-B2FC-5217-9E79-52C6C92CEFF8" xml:space="preserve">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    26
SELECT data FROM demo325 WHERE tm&gt;julianday('2006-11-08');
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    27
</codeblock> <p>This query works fine. The problem is that the “julianday('2006-11-08')” function gets called repeatedly, once for each row tested, even though the function returns the same value each time. It is much more efficient to call the function one time only and reuse the result over and over. You can accomplish this by moving the function call inside a subquery as follows: </p> <codeblock id="GUID-326760B0-E190-572D-ADD6-03786B6CB4FD" xml:space="preserve">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    28
SELECT data FROM demo325 WHERE tm&gt;(SELECT julianday('2006-11-08'));
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    29
</codeblock> <p>There are, of course, some cases where multiple evaluations of a function in the WHERE clause is desirable. For example, suppose you want to return roughly one out of every eight records, chosen at random. A suitable query would be: </p> <codeblock id="GUID-1E734B78-91B6-542E-9EDC-52A378944D48" xml:space="preserve">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    30
SELECT data FROM demo325 WHERE (random()&amp;7)==0;
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    31
</codeblock> <p>In this case, moving the function evaluation into a subquery would not work as desired: </p> <codeblock id="GUID-34B1C0C6-09E7-5994-9DD9-ABB4D5327BA7" xml:space="preserve">
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    32
SELECT data FROM demo325 WHERE (SELECT random()&amp;7)==0;
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    33
</codeblock> <p>In this last example, the result would be either all of the records in the table (probability 12.5%) or none of them (probability 87.5%). The difference here, of course, is that the <codeph>random()</codeph> function is not constant whereas the <codeph>julianday()</codeph> function is. </p> <p>The SQL compiler does not have any way of knowing this so it always assumes the worst: that every function works like <codeph>random()</codeph> and can potentially return a different answer even with the same inputs. Use a subquery if you truly want to make a subexpression constant. </p> </section> </conbody><related-links><link href="GUID-22844C28-AB5B-5A6F-8863-7269464684B4.dita"><linktext>SQL Overview</linktext> </link> <link href="GUID-78773BCA-ADF6-53E6-AC80-5CB2AE1F8BCC.dita"><linktext>SQL Server Guide</linktext> </link> <link href="GUID-E51836E1-D33E-506C-B75B-19B8E3CC313A.dita"><linktext>SQLite</linktext> </link> <link href="GUID-1F12E3F5-45B2-55EC-B021-00338277C608.dita"><linktext>SQL DB Overview</linktext> </link> <link href="GUID-43CA02E7-0101-5824-B91B-E15EE20C829A.dita"><linktext>Avoid Transient
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    34
                Tables</linktext> </link> <link href="GUID-49A3419F-D20A-5C5D-B2FF-51724EF37704.dita"><linktext>Prevent
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    35
                Datafile Corruption</linktext> </link> <link href="GUID-C2FAEBB2-4A1A-5BB0-9670-4801525CBC6A.dita"><linktext>SQL Index
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    36
                Tips</linktext> </link> <link href="GUID-B994E6F7-228A-5433-B87F-91857C5D93D6.dita"><linktext>SQL Insertion
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    37
                Tips</linktext> </link> <link href="GUID-4FC23DB7-4758-5DA4-81FF-0DAB169E2757.dita"><linktext>SQL Schema
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    38
                Tips</linktext> </link> <link><linktext/></link><link href="GUID-126FCCCC-0E7D-59AE-959A-2F94A7319C4B.dita"><linktext>SQL Statement
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    39
                Tips</linktext> </link> <link href="GUID-ACCCB148-DAF9-59EC-B585-8EF632B9BF04.dita"><linktext>SQL Joins</linktext> </link> <link href="GUID-B7E978C1-45CA-554C-8028-D901B97BA2E0.dita"><linktext> ANALYZE
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    40
                Command</linktext> </link> <link href="GUID-AF5A75D7-0687-546C-87B2-0B7DF7D33217.dita"><linktext> SQL WHERE CLause
89d6a7a84779 Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385
Dominic Pinkman <Dominic.Pinkman@Nokia.com>
parents:
diff changeset
    41
                Tips</linktext> </link> </related-links></concept>