我一直只使用“SELECT COUNT(1) FROM X”,但这也许不是最有效的。有什么想法吗?其他选项包括 SELECT COUNT(*) 或获取最后插入的 id(如果它是自动递增的(且从未删除))。
如果我只是想知道表中是否有任何内容怎么样? (例如,计数 > 0?)
最好的方法是确保在单个列上运行
SELECT COUNT
(SELECT COUNT(*)
速度较慢) - 但 SELECT COUNT
始终是获取事物计数的最快方法(数据库在内部优化查询) .
如果您查看下面的评论,您可以看到为什么
SELECT COUNT(1)
可能是您的最佳选择的论据。
为了跟进 girasquid 的答案,作为数据点,我有一个包含 230 万行的 sqlite 表。使用
select count(*) from table
,计算行数需要 3 秒多的时间。我还尝试使用 SELECT count(rowid) FROM table
(认为 rowid 是默认的主索引键),但这并没有更快。然后我在数据库中的一个字段上建立了索引(只是一个任意字段,但我选择了一个整数字段,因为我从过去的经验中知道,短字段上的索引可以非常快,我认为因为索引存储了一个副本索引本身的值)。 SELECT count(my_short_field) FROM table
将时间缩短到不到一秒。
如果您确定(确实确定)从未从该表中删除任何行,并且您的表尚未使用WITHOUT ROWID 优化进行定义,您可以通过调用以下命令来获取行数:
select max(RowId) from table;
或者如果你的桌子是一个循环队列,你可以使用类似的东西
select MaxRowId - MinRowId + 1 from
(select max(RowId) as MaxRowId from table) JOIN
(select min(RowId) as MinRowId from table);
这真的非常快(毫秒),但是你必须注意,因为sqlite说row id在同一个表中的所有行中是唯一的。 SQLite 没有声明行 id 始终是连续的数字。
获取行计数的最快方法是直接从表元数据(如果有)中获取。不幸的是,我找不到 SQLite 中可用的此类数据的参考。
如果失败,任何类型的查询
从表中选择 COUNT(非 NULL 常量值)
应该进行优化以避免对表甚至索引扫描的需要。理想情况下,引擎将简单地从内部元数据返回表中已知的当前行数。如果做不到这一点,它只需要知道任何非 NULL 列的索引中的条目数(主键索引是第一个查看的地方)。
一旦在 SELECT COUNT 中引入一列,您就会要求引擎至少执行一次索引扫描,可能还执行一次表扫描,这会变慢。
我不相信你会为此找到特殊的方法。但是,您可以对主键进行选择计数,这样会更快一点。
sp_spaceused 'table_name'
(不包括单引号)
这将返回上表中的行数,这是我遇到的最有效的方法。
比
select Count(1) from 'table_name'
更有效率(不包括单引号)
sp_spaceused
可以用于任何表,当表特别大(数亿行)时非常有帮助,可以正确返回行数,而'select Count(1)'
可能需要10秒以上。而且,它不需要考虑任何列名/关键字段。