【问题标题】:Will using IFNULL prevent SQLite from using an index?使用 IFNULL 会阻止 SQLite 使用索引吗?
【发布时间】:2014-04-02 13:12:27
【问题描述】:

假设我有一个表T 和字段f 的索引。我想根据一些整数myF 过滤f。如果整数为 0,我想要 fnull 的所有记录。一个可靠的写法是:

db.rawQuery("SELECT someField FROM T WHERE "
        + (myF == 0 ? "f IS NULL" : "f = ?"),
        (myF == 0 ? new String[] {}, new String[] {String.valueOf(myF)}));

这有点不方便;特别是如果查询比这更复杂并且有额外的参数。所以我想我会写

db.rawQuery("SELECT someField FROM T WHERE IFNULL(f, 0) = ?", 
        new String[] {String.valueOf(myF)});

相反,它更简单、更易于阅读和更易于维护。¹

我的问题是:如果f 上有索引,SQLite 是否仍会使用该索引,还是会诉诸表扫描?我问是因为在后一种情况下我' m 不是比较字段和参数,而是比较 表达式 和参数,我不确定 SQLite 查询优化器有多“智能”。


¹ 请注意,数据库中没有带有f = 0 的记录。

【问题讨论】:

    标签: android sql sqlite indexing


    【解决方案1】:

    这将导致表扫描。

    使用 sqlite3 命令行客户端的示例:

    sqlite> create table t(f);
    sqlite> create index tf on t(f);
    sqlite> explain query plan select * from t where ifnull(f,0)=1;
    0|0|0|SCAN TABLE t (~500000 rows)
    sqlite> explain query plan select * from t where f is null;
    0|0|0|SEARCH TABLE t USING COVERING INDEX tf (f=?) (~10 rows)
    sqlite> explain query plan select * from t where f=1;
    0|0|0|SEARCH TABLE t USING COVERING INDEX tf (f=?) (~10 rows)
    

    【讨论】:

      猜你喜欢
      • 2018-10-30
      • 2022-10-20
      • 2016-10-21
      • 1970-01-01
      • 2011-12-19
      • 2018-10-07
      • 2012-07-31
      • 2013-06-11
      • 1970-01-01
      相关资源
      最近更新 更多