172 lines
6.8 KiB
HTML
172 lines
6.8 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html><head>
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||
|
<link href="sqlite.css" rel="stylesheet">
|
||
|
<title>The INDEXED BY Clause</title>
|
||
|
<!-- path= -->
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class=nosearch>
|
||
|
<a href="index.html">
|
||
|
<img class="logo" src="images/sqlite370_banner.gif" alt="SQLite" border="0">
|
||
|
</a>
|
||
|
<div><!-- IE hack to prevent disappearing logo --></div>
|
||
|
<div class="tagline desktoponly">
|
||
|
Small. Fast. Reliable.<br>Choose any three.
|
||
|
</div>
|
||
|
<div class="menu mainmenu">
|
||
|
<ul>
|
||
|
<li><a href="index.html">Home</a>
|
||
|
<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a>
|
||
|
<li class='wideonly'><a href='about.html'>About</a>
|
||
|
<li class='desktoponly'><a href="docs.html">Documentation</a>
|
||
|
<li class='desktoponly'><a href="download.html">Download</a>
|
||
|
<li class='wideonly'><a href='copyright.html'>License</a>
|
||
|
<li class='desktoponly'><a href="support.html">Support</a>
|
||
|
<li class='desktoponly'><a href="prosupport.html">Purchase</a>
|
||
|
<li class='search' id='search_menubutton'>
|
||
|
<a href="javascript:void(0)" onclick='toggle_search()'>Search</a>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="menu submenu" id="submenu">
|
||
|
<ul>
|
||
|
<li><a href='about.html'>About</a>
|
||
|
<li><a href='docs.html'>Documentation</a>
|
||
|
<li><a href='download.html'>Download</a>
|
||
|
<li><a href='support.html'>Support</a>
|
||
|
<li><a href='prosupport.html'>Purchase</a>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="searchmenu" id="searchmenu">
|
||
|
<form method="GET" action="search">
|
||
|
<select name="s" id="searchtype">
|
||
|
<option value="d">Search Documentation</option>
|
||
|
<option value="c">Search Changelog</option>
|
||
|
</select>
|
||
|
<input type="text" name="q" id="searchbox" value="">
|
||
|
<input type="submit" value="Go">
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
<script>
|
||
|
function toggle_div(nm) {
|
||
|
var w = document.getElementById(nm);
|
||
|
if( w.style.display=="block" ){
|
||
|
w.style.display = "none";
|
||
|
}else{
|
||
|
w.style.display = "block";
|
||
|
}
|
||
|
}
|
||
|
function toggle_search() {
|
||
|
var w = document.getElementById("searchmenu");
|
||
|
if( w.style.display=="block" ){
|
||
|
w.style.display = "none";
|
||
|
} else {
|
||
|
w.style.display = "block";
|
||
|
setTimeout(function(){
|
||
|
document.getElementById("searchbox").focus()
|
||
|
}, 30);
|
||
|
}
|
||
|
}
|
||
|
function div_off(nm){document.getElementById(nm).style.display="none";}
|
||
|
window.onbeforeunload = function(e){div_off("submenu");}
|
||
|
/* Disable the Search feature if we are not operating from CGI, since */
|
||
|
/* Search is accomplished using CGI and will not work without it. */
|
||
|
if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){
|
||
|
document.getElementById("search_menubutton").style.display = "none";
|
||
|
}
|
||
|
/* Used by the Hide/Show button beside syntax diagrams, to toggle the */
|
||
|
function hideorshow(btn,obj){
|
||
|
var x = document.getElementById(obj);
|
||
|
var b = document.getElementById(btn);
|
||
|
if( x.style.display!='none' ){
|
||
|
x.style.display = 'none';
|
||
|
b.innerHTML='show';
|
||
|
}else{
|
||
|
x.style.display = '';
|
||
|
b.innerHTML='hide';
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
</script>
|
||
|
</div>
|
||
|
<div class=fancy>
|
||
|
<div class=nosearch>
|
||
|
<div class="fancy_title">
|
||
|
The INDEXED BY Clause
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<h1 id="how_indexed_by_works"><span>1. </span>How INDEXED BY Works</h1>
|
||
|
|
||
|
<p>The INDEXED BY phrase forces the <a href="optoverview.html">SQLite query planner</a> to use a
|
||
|
particular named index on a <a href="lang_delete.html">DELETE</a>, <a href="lang_select.html">SELECT</a>, or <a href="lang_update.html">UPDATE</a> statement.
|
||
|
The INDEXED BY phrase is an SQLite extension and
|
||
|
is not portable to other SQL database engines.</p>
|
||
|
|
||
|
<p><b><a href="syntax/qualified-table-name.html">qualified-table-name:</a></b>
|
||
|
<button id='x1691' onclick='hideorshow("x1691","x1692")'>hide</button></p>
|
||
|
<div id='x1692' class='imgcontainer'>
|
||
|
<img alt="syntax diagram qualified-table-name" src="images/syntax/qualified-table-name.gif" />
|
||
|
</div>
|
||
|
|
||
|
|
||
|
<p>The "INDEXED BY <span class='yyterm'>index-name</span>" phrase specifies
|
||
|
that the named index
|
||
|
must be used in order to look up values on the preceding table.
|
||
|
If <span class='yyterm'>index-name</span> does not exist or cannot be used
|
||
|
for the query, then the preparation of the SQL statement fails.
|
||
|
The "NOT INDEXED" clause specifies that no index shall be used when
|
||
|
accessing the preceding table, including implied indices create by
|
||
|
UNIQUE and PRIMARY KEY constraints. However, the <a href="lang_createtable.html#rowid">rowid</a>
|
||
|
can still be used to look up entries even when "NOT INDEXED" is specified.</p>
|
||
|
|
||
|
<p>Some SQL database engines provide non-standard "hint" mechanisms which
|
||
|
can be used to give the query optimizer clues about what indices it should
|
||
|
use for a particular statement. The INDEX BY clause of SQLite is
|
||
|
<em>not</em> a hinting mechanism and it should not be used as such.
|
||
|
The INDEXED BY clause does not give the optimizer hints about which index
|
||
|
to use; it gives the optimizer a requirement of which index to use.
|
||
|
If the query optimizer is unable to use the index specified by the
|
||
|
INDEX BY clause, then the query will fail with an error.</p>
|
||
|
|
||
|
<p>The INDEXED BY clause is <em>not</em> intended for use in tuning
|
||
|
the performance of a query. The intent of the INDEXED BY clause is
|
||
|
to raise a run-time error if a schema change, such as dropping or
|
||
|
creating an index, causes the query plan for a time-sensitive query
|
||
|
to change. The INDEXED BY clause is designed to help detect
|
||
|
undesirable query plan changes during regression testing.
|
||
|
Application
|
||
|
developers are admonished to omit all use of INDEXED BY during
|
||
|
application design, implementation, testing, and tuning. If
|
||
|
INDEXED BY is to be used at all, it should be inserted at the very
|
||
|
end of the development process when "locking down" a design.</p>
|
||
|
|
||
|
<h1 id="see_also"><span>2. </span>See Also</h1>
|
||
|
|
||
|
<ol>
|
||
|
<li><p>The <a href="queryplanner-ng.html#howtofix">query planner checklist</a> describes steps that application
|
||
|
developers should following to help resolve query planner problems.
|
||
|
Notice the that the use of INDEXED BY is a last resort, to be used only
|
||
|
when all other measures fail.</p>
|
||
|
|
||
|
</li><li><p><a href="optoverview.html#uplus">The unary "+" operator</a>
|
||
|
can be used to disqualify terms in the WHERE clause from use by indices.
|
||
|
Careful use of unary + can sometimes help prevent the query planner from
|
||
|
choosing a poor index without restricting it to using one specific index.
|
||
|
Careful placement of unary + operators is a better method for controlling
|
||
|
which indices are used by a query.</p>
|
||
|
|
||
|
</li><li><p>The <a href="c3ref/stmt_status.html">sqlite3_stmt_status()</a> C/C++ interface together with the
|
||
|
<a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatusfullscanstep">SQLITE_STMTSTATUS_FULLSCAN_STEP</a> and <a href="c3ref/c_stmtstatus_counter.html#sqlitestmtstatussort">SQLITE_STMTSTATUS_SORT</a> verbs
|
||
|
can be used to detect at run-time when an SQL statement is not
|
||
|
making effective use of indices. Many applications may prefer to
|
||
|
use the <a href="c3ref/stmt_status.html">sqlite3_stmt_status()</a> interface to detect index misuse
|
||
|
rather than the INDEXED BY phrase described here.</p>
|
||
|
</li></ol>
|
||
|
|