【问题标题】:optimized way to check if table is empty SQLite检查表是否为空的优化方法 SQLite
【发布时间】:2023-03-15 17:07:01
【问题描述】:

我正在处理一个数据库有多个表的项目。这些表中有些是空的,有些包含几百万行。我需要检查一个表是否为空。这是一段代码(提取所需部分):

private boolean isEmpty(Uri uri){
   ContentResolver cr = getContext().getContentResolver();
   Cursor cursor = cr.query(uri, new String[]{COUNT(_id)}, null, null, null);
   if(cursor.moveToFirst())
     return cursor.getInt(0) == 0;
   return true;
}

但是,由于某些文件包含很多行,count(_id) 会花费大量时间,并导致超时。 SQLite 中是否有其他方法可以优化此过程?

P.S: _id 是表的主键,不能为空。

【问题讨论】:

  • 查询没问题;您的 ContentResolver 实现可能会产生很多开销。
  • @laalto 你的意思是 count(_id) 一百万行不会影响性能?或者 ContentResolver 实现的开销会比它高得多?我阅读了多个页面,可以使用普通 SQL 语句:Select 1 from table LIMIT 1 但是如何在这里实现呢?
  • count()等聚合函数只返回一行,所以限制结果集为一行没有实际效果。
  • count 会遍历所有的_id,意思是遍历整个表,我不需要。如果我能确认至少存在 1 行,我的工作就会完成。 select 1 from table 将为表格的每一行返回常量 1。
  • IIRC 对索引列的计数应该比全表扫描更快,并且主键被索引。您也可以尝试COUNT(*) 看看是否更适合您。

标签: java android sqlite count android-sqlite


【解决方案1】:

如果您可以将SQLiteOpenHelper 类与ContentResolver 结合使用来执行rawQuery(),那么一种简单的方法可以得到1(表包含行)或0(表为空),是EXISTS的使用:

SELECT EXISTS (SELECT 1 FROM tablename) AS result

在这种情况下,如果表不为空,EXISTS 将停止并在找到第一行后立即返回值1

【讨论】:

  • 虽然我理解你上面解释的概念,但是使用 SQLiteOpenHelper 需要在我的其余代码中做一些更多的更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
  • 2014-07-04
相关资源
最近更新 更多