以下是我用于从具有数百万条记录的数据库中获取固定数量记录的查询: -
select * from myTable LIMIT 100 OFFSET 0
Run Code Online (Sandbox Code Playgroud)
我观察到的是,如果偏移量非常高,比如说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
Run Code Online (Sandbox Code Playgroud)
任何人都可以建议我如何优化此查询?我的意思是,对于我希望从任何OFFSET检索的任何数量的记录,查询执行时间应该相同且快速.
新增: - 实际情况是我的数据库有超过100万条记录.但由于它是一个嵌入式设备,我不能做"select*from myTable",然后从查询中获取所有记录.我的设备崩溃了.相反,我所做的是按照上面提到的查询逐批获取记录(批量大小= 100或1000条记录).但正如我所提到的,随着偏移的增加,它变得缓慢.所以,我的最终目标是我想从数据库中读取所有记录.但由于我无法在一次执行中获取所有记录,我需要一些其他有效的方法来实现这一点.
正如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!
Run Code Online (Sandbox Code Playgroud)
通过执行偏移量为95000的查询,将处理所有以前的95000记录。您应该在表上创建一些索引,并将其用于选择记录。
正如@user318750 所说,如果你知道你有一个连续的索引,你可以简单地使用
select * from Table where index >= %start and index < %(start+size)
Run Code Online (Sandbox Code Playgroud)
但是,这些情况很少见。如果您不想依赖该假设,请使用子查询,例如 using rowid
,它始终被编入索引,
select * from Table where rowid in (
select rowid from Table limit %size offset %start)
Run Code Online (Sandbox Code Playgroud)
这会加快速度,特别是如果您有“胖”行(例如,包含 blob)。
如果维护记录顺序很重要(通常不是),您需要先对索引进行排序:
select * from Table where rowid in (
select rowid from Table order by rowid limit %size offset %start)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5418 次 |
最近记录: |