当我在某个列上创建索引时,index是可识别数据类型的,但是我可以在任何列中存储任何类型的数据,但如果我想使用不同的比较规则比较列内容,它会使索引变得无用,例如:将数字比作数字,而不是字符串。
示例:
sqlite> create table foo (key varchar, value varchar);
sqlite> create index foo_ndx on foo (key, value);
sqlite> insert into foo values ('bar', 10);
sqlite> select * from foo where key = 'bar' and value > 9.0;
sqlite> explain query plan select * from foo where key = 'bar' and value > 9.0;
0|0|0|SEARCH TABLE foo USING COVERING INDEX foo_ndx (key=? AND value>?) (~2 rows)
在这种情况下,9.0
被隐式转换为varchar
并且两个varchars
被比较,索引被完全使用,但无法找到记录。
sqlite> select * from foo where key = 'bar' and CAST(value AS REAL) > 9.0;
bar|10
sqlite> explain query plan select * from foo where key = 'bar'
...> and CAST(value AS REAL) > 9.0;
0|0|0|SEARCH TABLE foo USING COVERING INDEX foo_ndx (key=?) (~5 rows)
在这种情况下,我明确地将value
转换为real
并对两个reals
进行比较,sqlite找到记录,但索引仅部分使用。
这是可以理解的行为,但是我可以以某种方式在foo
表上创建将列value
视为REAL的索引吗?我已尝试在CAST
中使用CREATE INDEX
,但语法错误,我可以使用foo
在CAST
表上创建视图,但无法在视图上创建索引。
答案 0 :(得分:1)
索引 数据类型无法识别。
默认情况下,如果可能,value
列中的值会被视为文本,因为该列包含文本affinity。
使用索引不会改变此行为。
如果您不想将数字视为文本,请不要将该列声明为varchar
。 (注意:您可以声明没有任何数据类型的列。)