简而言之:一个包含超过1600万条记录的表[大小为2GB].使用ORDER BY*primary_key时,使用SELECT的LIMIT偏移越高,查询变得越慢
所以
SELECT * FROM large ORDER BY `id` LIMIT 0, 30
Run Code Online (Sandbox Code Playgroud)
远远不及
SELECT * FROM large ORDER BY `id` LIMIT 10000, 30
Run Code Online (Sandbox Code Playgroud)
这也只能订购30条记录.所以这不是ORDER BY的开销.
现在,当获取最新的30行时,大约需要180秒.如何优化该简单查询?
有没有办法使用线程同时执行 SQL 查询,这样我就可以减少下面代码的处理时间?有没有更好的方法可以在不使用 pandas 模块的情况下执行与下面相同的结果?鉴于我正在使用的数据集的大小,我无法将整个数据集存储在内存中,我发现循环遍历 SELECT * FROM 语句的行并将它们与我正在查询的列表进行比较会增加处理时间。
# DATABASE layout
# _____________________________________________________________
# | id | name | description |
# |_____________|____________________|__________________________|
# | 1 | John | Credit Analyst |
# | 2 | Jane | Doctor |
# | ... | ... | ... |
# | 5000000 | Mohammed | Dentist |
# |_____________|____________________|__________________________|
import sqlite3
SEARCH_IDS = [x for x in range(15000)]
DATABASE_NAME = 'db.db'
def chunks(wholeList, chunkSize=999):
"""Yield successive n-sized chunks from wholeList.""" …Run Code Online (Sandbox Code Playgroud) 我正在编写自己的 SQLIteBrowser,并且有最后一个问题,这显然在网络上经常讨论,但似乎没有一个好的通用解决方案。
所以目前我存储用户输入的SQL。每当我需要获取行时,我都会通过在 SQL 末尾添加“Limit n, m”来执行 SQL。
对于我主要使用的普通 SQL,这似乎已经足够了。但是,如果我想在查询中使用 limit 自己,这显然会给出错误,因为生成的 sql 可能如下所示:
select * from table limit 30 limit 1,100
Run Code Online (Sandbox Code Playgroud)
这显然是错误的。有更好的方法来做到这一点吗?
我的想法是,我可以扫描 SQL 并检查是否已经使用了限制子句,然后忽略它。当然它不是那么简单,因为如果我有这样的sql:
select * from a where a.b = ( select x from z limit 1)
Run Code Online (Sandbox Code Playgroud)
显然在这种情况下它仍然应该应用我的限制,所以我可以从末尾扫描字符串并查看是否存在限制。我现在的问题是,这有多可行。由于我不知道 SQL 解析器是谁工作的,所以我不确定 LIMIT 是否必须位于 SQL 的末尾,或者末尾是否还可以有其他命令。
我用order byand测试了它,如果不是最后,group by我会得到 SQL 错误,所以我的假设似乎是正确的。limit
sqlite ×3
limit ×2
android ×1
mysql ×1
paging ×1
performance ×1
python ×1
sql ×1
sql-order-by ×1