在SQLite中计算表中行的最有效方法是什么?

[英]What is the most efficient way to count rows in a table in SQLite?


I've always just used "SELECT COUNT(1) FROM X" but perhaps this is not the most efficient. Any thoughts? Other options include SELECT COUNT(*) or perhaps getting the last inserted id if it is auto-incremented (and never deleted).

我总是只使用“SELECT COUNT(1)FROM X”,但也许这不是最有效的。有什么想法吗?其他选项包括SELECT COUNT(*)或者如果它是自动递增(并且从不删除),则可能获取最后插入的id。

How about if I just want to know if there is anything in the table at all? (e.g., count > 0?)

如果我只是想知道桌子上是否有任何东西怎么样? (例如,计数> 0?)

6 个解决方案

#1


13  

The best way is to make sure that you run SELECT COUNT on a single column (SELECT COUNT(*) is slower) - but SELECT COUNT will always be the fastest way to get a count of things (the database optimizes the query internally).

最好的方法是确保在单个列上运行SELECT COUNT(SELECT COUNT(*)更慢) - 但SELECT COUNT始终是获取事物数量的最快方法(数据库在内部优化查询)。

If you check out the comments below, you can see arguments for why SELECT COUNT(1) is probably your best option.

如果你看看下面的评论,你可以看到为什么SELECT COUNT(1)可能是你最好的选择。

#2


0  

I do not believe you will find a special method for this. However, you could do your select count on the primary key to be a little bit faster.

我不相信你会找到一个特殊的方法。但是,您可以对主键进行选择计数,使其更快一些。

#3


0  

The fastest way to get row counts is directly from the table metadata, if any. Unfortunately, I can't find a reference for this kind of data being available in SQLite.

获取行计数的最快方法是直接从表元数据中获取(如果有)。不幸的是,我找不到SQLite中可用的这类数据的参考。

Failing that, any query of the type

没错,任何类型的查询

SELECT COUNT(non-NULL constant value) FROM table

SELECT COUNT(非NULL常量值)FROM表

should optimize to avoid the need for a table, or even an index, scan. Ideally the engine will simply return the current number of rows known to be in the table from internal metadata. Failing that, it simply needs to know the number of entries in the index of any non-NULL column (the primary key index being the first place to look).

应优化以避免需要扫描表,甚至是索引。理想情况下,引擎将简单地从内部元数据返回已知在表中的当前行数。如果不这样做,它只需要知道任何非NULL列的索引中的条目数(主键索引是第一个要查看的位置)。

As soon as you introduce a column into the SELECT COUNT you are asking the engine to perform at least an index scan and possibly a table scan, and that will be slower.

一旦将列引入SELECT COUNT,您就要求引擎至少执行索引扫描并可能执行表扫描,这样会慢一些。

#4


0  

If you are sure (really sure) that you've never deleted any row from that table and your table has not been defined with the WITHOUT ROWID optimization you can have the number of rows by calling:

如果您确定(非常确定)您从未删除该表中的任何行,并且尚未使用WITHOUT ROWID优化定义您的表,则可以通过调用来获取行数:

select max(RowId) from table;

Or if your table is a circular queue you could use something like

或者,如果您的表是循环队列,您可以使用类似的东西

select MaxRowId - MinRowId + 1 from
  (select max(RowId) as MaxRowId from table) JOIN
  (select min(RowId) as MinRowId from table);

This is really really fast (milliseconds), but you must pay attention because sqlite says that row id is unique among all rows in the same table. SQLite does not declare that the row ids are and will be always consecutive numbers.

这真的很快(毫秒),但你必须注意,因为sqlite说行id在同一个表中的所有行中是唯一的。 SQLite没有声明行ID是并且将始终是连续的数字。

#5


0  

To follow up on girasquid's answer, as a data point, I have a sqlite table with 2.3 million rows. Using select count(*) from table, it took over 3 seconds to count the rows. I also tried using SELECT rowid FROM table, (thinking that rowid is a default primary indexed key) but that was no faster. Then I made an index on one of the fields in the database (just an arbitrary field, but I chose an integer field because I knew from past experience that indexes on short fields can be very fast, I think because the index is stored a copy of the value in the index itself). SELECT my_short_field FROM table brought the time down to less than a second.

为了跟进girasquid的答案,作为一个数据点,我有一个包含230万行的sqlite表。使用表中的select count(*),计算行数需要3秒钟。我也尝试过使用SELECT rowid FROM table,(认为rowid是一个默认的主索引键),但这并不快。然后我在数据库中的一个字段上做了一个索引(只是一个任意字段,但我选择了一个整数字段,因为我从过去的经验中知道短字段上的索引可以非常快,我认为因为索引存储了一个副本索引本身的价值)。 SELECT my_short_field FROM table将时间缩短到不到一秒。

#6


-1  

sp_spaceused 'table_name' (exclude single quote)

sp_spaceused'table_name'(不包括单引号)

this will return the number of rows in the above table, this is the most efficient way i have come across yet.

这将返回上表中的行数,这是我遇到的最有效的方法。

it's more efficient than select Count(1) from 'table_name' (exclude single quote)

它比'table_name'中的select Count(1)更有效(不包括单引号)

sp_spaceused can be used for any table, it's very helpful when the table is exceptionally big (hundreds of millions of rows), returns number of rows right a way, whereas 'select Count(1)' might take more than 10 seconds. Moreover, it does not need any column names/key field to consider.

sp_spaceused可用于任何表,当表格特别大(数亿行)时,它非常有用,返回行数,而“select Count(1)”可能需要10秒以上。而且,它不需要考虑任何列名/密钥字段。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2010/12/17/b68facb387b3d76b76d776faea3fdd55.html



 
© 2014-2018 ITdaan.com 粤ICP备14056181号