As usual your answer is perfect in explanation!
Thank you very much.
On Jan 24, 2008 2:49 AM, [EMAIL PROTECTED] wrote:
Alexander Batyrshin [EMAIL PROTECTED] wrote:
Hello All,
I've found that SQLite-3.5.4 doesnt use index in this situation:
sqlite create table t1 (id int primary key, val int);
sqlite create table t2 (id unique, val int primary key);
sqlite explain query plan update t1 set val = (select t2.val from t2
where t1.id = t2.id);
0|0|TABLE t1
0|0|TABLE t2
In this case, SQLite should takes value from t2 via unique id INDEX,
but it doesn't
The t2.id field has no datatype specified. That means it has
an affinity of NONE. (See http://www.sqlite.org/datatypes3.html
paragraph 2.1 bullet 3.) That means that if you insert a string
into t2.id it goes in as a string:
INSERT INTO t2(id) VALUES('123');
SELECT typeof(id) FROM t2 WHERE rowid=last_insert_rowid();
-- answer text
Or if you insert an integer, it goes in as an integer:
INSERT INTO t2(id) VALUES(123);
SELECT typeof(id) FROM t2 WHERE rowid=last_insert_rowid();
-- answer integer
But the t1.id column to which you are comparing t2.id has
an affinity of INTEGER. (paragraph 2.1 bullet 1.) That means
if you insert a string it is converted into an integer if it
looks like an integer.
INSERT INTO t1(id) VALUES('123');
SELECT typeof(id) FROM t1 WHERE rowid=last_insert_rowid();
-- answer integer
Now, the index on t2(id) also uses NO-affinity because the
affinity of the column is NONE. So the index stores separate
entries in separate places for '123' and 123. But the value
you are comparing against is always an integer, because it is
coming out of t1.id which has integer affinity. So if you
look up the entry using just the integer value 123, you will
miss the '123' entry. That is unacceptable. Hence, you cannot
use a value with INTEGER-affinity as the key to an index
with NO-affinity.
Hence the index on t2.id cannot be used to speed the search.
You can get the index to work by saying:
create table t1(id int primary key, val int);
create table t2(id INT unique, val int primary key);
Note the added INT in the definition of t2.id, thus
giving it integer affinity. You'll still be able to store
text in t2.id if you want to, but if that text looks like
an integer, it is converted into an integer.
Please also not that INT PRIMARY KEY is not the same
thing as INTEGER PRIMARY KEY. You probably want
to use INTEGER PRIMARY KEY in this context, not what
you have - but that is a whole other issue.
--
D. Richard Hipp [EMAIL PROTECTED]
-
To unsubscribe, send email to [EMAIL PROTECTED]
-
--
Alexander Batyrshin aka bash
bash = Biomechanica Artificial Sabotage Humanoid
-
To unsubscribe, send email to [EMAIL PROTECTED]
-