【问题标题】:Valid query to check if row exists in SQLite3用于检查 SQLite3 中是否存在行的有效查询
【发布时间】:2012-03-18 03:55:48
【问题描述】:

这是检查表中是否存在行的最有效方法吗?

SELECT EXISTS(SELECT 1 FROM myTbl WHERE u_tag="tag");

表是...

CREATE TABLE myTbl(id INT PRIMARY KEY, u_tag TEXT);

如果该行不存在,那么返回值是多少?是 false (bool) 还是 0 (int) 还是 NULL?

【问题讨论】:

    标签: sqlite


    【解决方案1】:

    虽然文档没有暗示,但显然主要的 sqlite 开发人员 (Richard Hipp) 有 confirmed in the mailing listEXISTS 短路。

    SQLite 中的查询计划器虽然不是很出色,但足够聪明 知道它可以在看到第一行时立即停止并返回 true 来自 EXISTS() 内部的查询。

    所以你提出的查询将是最有效的:

    SELECT EXISTS(SELECT 1 FROM myTbl WHERE u_tag="tag");
    

    如果您担心可移植性,可以添加限制。不过,我怀疑大多数 DB 会为您提供相同的短路。

    SELECT EXISTS(SELECT 1 FROM myTbl WHERE u_tag="tag" LIMIT 1);
    

    如果您不需要记录中的某些内容,则选择 1 是公认的做法,尽管您选择的内容并不重要。

    在您的标签字段上放置一个索引。如果不这样做,对不存在标签的查询将执行全表扫描。

    EXISTS 声明它将返回 1 或 0,而不是 null。

    【讨论】:

    • EXISTS 总是返回一个结果,所以只检查值就可以了。
    • 可以肯定的是,检查游标的值是否为 int 是 getInt(0) 正确的吗?
    • @BenSewards 最初的问题不是特定于语言的,所以我只能在您的平台上猜测这是正确的。我建议尝试一下。
    • @BenSewards 您可以使用别名方法,例如: SELECT EXISTS(SELECT 1 FROM myTbl WHERE u_tag="tag") AS alias_naming;然后你可以使用 cursor.getInt("alias_naming") 来获取值。
    • @Lynn 这是来自 SQLite 原作者 Richard Hipp 的comment:“SQLite 中的查询计划器虽然不出色,但足够聪明,知道它可以停止并尽快返回 true因为它看到 EXISTS() 内部查询的第一行。"
    【解决方案2】:

    再次引用the documentation

    EXISTS 运算符的计算结果始终为整数值 0 和 1。如果执行指定为 EXISTS 运算符右侧操作数的 SELECT 语句将返回一行或多行,则 EXISTS 运算符的计算结果为 1。如果执行 SELECT 将根本不返回任何行,然后 EXISTS 运算符的计算结果为 0。

    至于使用EXISTS 是否比使用count(*) 更有效,这可能取决于表的大小以及表是否有索引。尝试在两个查询上使用EXPLAIN 进行基准测试(或对每个查询进行计时)。

    【讨论】:

      猜你喜欢
      • 2015-07-14
      • 2013-09-19
      • 2012-05-20
      • 1970-01-01
      • 2022-01-12
      • 2018-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多