15

以下是我用于从具有数百万条记录的数据库中获取固定数量记录的查询:-

select * from myTable LIMIT 100 OFFSET 0

我观察到的是,如果偏移量非常高,比如 90000,那么执行查询需要更多时间。以下是具有不同偏移量的 2 个查询之间的时间差:

select * from myTable LIMIT 100 OFFSET 0       //Execution Time is less than 1sec
select * from myTable LIMIT 100 OFFSET 95000   //Execution Time is almost 15secs

谁能建议我如何优化此查询?我的意思是,对于我希望从任何 OFFSET 检索的任意数量的记录,查询执行时间应该相同且快速。

新增:- 实际情况是我有一个数据库超过 100 万条记录。但由于它是嵌入式设备,我不能执行“select * from myTable”然后从查询中获取所有记录。我的设备崩溃了。相反,我所做的是按照上面提到的查询逐批(批量大小 = 100 或 1000 条记录)获取记录。但正如我所提到的,随着偏移量的增加,它变得很慢。所以,我的最终目标是我想从数据库中读取所有记录。但由于我无法在一次执行中获取所有记录,因此我需要一些其他有效的方法来实现这一点。

4

5 回答 5

9

正如JvdBerg所说,LIMIT/OFFSET 中不使用索引。简单地添加 'ORDER BY indexed_field' 也无济于事。

为了加快分页速度,您应该避免使用 LIMIT/OFFSET 并改用 WHERE 子句。例如,如果您的主键字段名为 'id' 并且没有空格,那么您上面的代码可以这样重写:

SELECT * FROM myTable WHERE id>=0     AND id<100     //very fast!
SELECT * FROM myTable WHERE id>=95000 AND id<95100   //as fast as previous line!
于 2015-05-08T13:02:01.560 回答
7

通过执行偏移量为 95000 的查询,所有之前的 95000 条记录都会被处理。您应该在表上创建一些索引,并将其用于选择记录。

于 2012-09-04T14:52:14.163 回答
5

正如@user318750 所说,如果你知道你有一个连续的索引,你可以简单地使用

select * from Table where index >= %start and index < %(start+size)

但是,这些情况很少见。如果您不想依赖该假设,请使用子查询,例如 using rowid,它始终被索引,

select * from Table where rowid in (
  select rowid from Table limit %size offset %start)

这会加快速度,特别是如果您有“胖”行(例如,包含 blob)。

如果维护记录顺序很重要(通常不重要),则需要先对索引进行排序:

select * from Table where rowid in (
  select rowid from Table order by rowid limit %size offset %start)
于 2018-04-04T12:27:09.903 回答
2
select * from data where rowid = (select rowid from data limit 1 offset 999999);
于 2021-01-09T21:22:28.677 回答
1

使用 SQLite,您不需要在一个大的胖数组中一次返回所有行,您可以为每一行回调。这样,您可以在结果进入时对其进行处理,这应该可以解决您的崩溃和性能问题。

我猜你没有使用 C,因为你已经使用了回调,但是这种技术应该可以在任何其他语言中使用。

Javascript 示例(来自:https ://www.npmjs.com/package/sqlite3 )

 db.each("SELECT rowid AS id, info FROM lorem", function(err, row) {
      console.log(row.id + ": " + row.info);
  });
于 2017-03-23T09:47:28.653 回答