sqlite - LIKE 语句可以优化成不做全表扫描吗?

标签 sqlite query-optimization sql-like

我想通过树路径从表中获取子树。

path 列存储如下字符串:

foo/
foo/bar/
foo/bar/baz/

如果我尝试选择以特定路径开头的所有记录:

EXPLAIN QUERY PLAN SELECT * FROM f WHERE path LIKE "foo/%"

它告诉我该表已被扫描,即使 path 列已编入索引 :(

有什么方法可以让 LIKE 使用索引而不扫描表吗?

我找到了一种方法来实现我想要的闭包表,但是它更难维护并且写入速度非常慢......

最佳答案

为了能够在 SQLite 中为 LIKE 使用索引,

  1. 表格列必须有 TEXT affinity ,即有一种 TEXT 或 VARCHAR 或类似的东西;和
  2. 索引必须声明为 COLLATE NOCASE(直接声明,或者因为该列已声明为 COLLATE NOCASE):

    > CREATE TABLE f(path TEXT);
    > CREATE INDEX fi ON f(path COLLATE NOCASE);
    > EXPLAIN QUERY PLAN SELECT * FROM f WHERE path LIKE 'foo/%';
    0|0|0|SEARCH TABLE f USING COVERING INDEX fi (path>? AND path<?)
    

可以使用 case_sensitive_like PRAGMA 删除第二个限制。 ,但这会改变 LIKE 的行为。 或者,可以使用区分大小写的比较,方法是将 LIKE 'foo/%' 替换为 GLOB 'foo/*'

关于sqlite - LIKE 语句可以优化成不做全表扫描吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20423387/

相关文章:

mysql - 如何加速这个 mysql 连接查询

php - 将字符串与 MySQL 列进行比较

where 子句中带有 like %..% 的 mysql 查询返回不同的结果

android - 如何在将 ArrayList 添加到 Android 中的 HashMap 后清除 ArrayList?

Perl 的 SQLite3 : {NAME} not working?

c# - 使用外键属性或导航属性查询?英孚 4.1

mysql - 优化查询以不使用文件排序

mysql - ORDER BY soundex 与 WHERE (MySql)

Android - 数据库被锁定

c - 处理 SQLite 数据库文件的路径更改