java - LIMIT OFFSET 是分页的最佳解决方案吗?
问题描述
解释:
我正在使用 SQLite 创建一个发票系统。数据库的表格包括:客户和发票。每个invoiceOBJ(14 列数据)包含一个customerOBJ(4 列数据),而每个invoiceOBJ 将包含一个customerID 来检索对应的客户。
根据我的理解和研究,我在发票表中随机生成了 100 万条记录(已过时?) , 100 万条记录略微推动了 sqlite(性能方面)
我将发票加载到 javaFX 表视图中的查询是
ResultSet rs = stmt.executeQuery(String.format("SELECT id,year,vin,carModel,condition,licenseState,regNum,stage,vehicleID,paintCode,dateOfInvoice," +
"bodyStyle,manufacturer, customerID FROM invoices LIMIT 100 OFFSET (SELECT COUNT(*) FROM invoices)-%d", indexStart));
indexStart 是通过 gui 翻阅发票的号码,可以是 -100 或 +100。
我想知道这是否是使用 sqlite 的最佳解决方案,因为每次用户决定进入下一页时,如果有 100 万张发票/记录,这平均需要 250-264 毫秒。那么在制作invoiceOBJ时每次查询获取customerOBJ平均为0.6-1ms*100(Limit),每次迭代的总时间通常在300ms左右。
实际上,100 万张发票超出了所需的 98%,但是,出于教育目的,我正努力使其尽可能高效。
澄清一下,我不是在问这个 sqlite 是否是最好的方法,而是在问这是否是 sqlite 中最好的方法。
sqlitedb Object ,相关方法:
public void connect() {
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:school.sqlite");
} catch (Exception e) {
e.printStackTrace();
}
}
public ArrayList<invoiceOBJ> listInvoices(int indexStart) {
//invoiceAmount = invoices to index.
ArrayList<invoiceOBJ> invoices = new ArrayList<>();
//System.out.println(indexStart + "index start");
try {
connect();
stmt = c.createStatement();
stmt.setFetchSize(100);
ResultSet rs = stmt.executeQuery(String.format("SELECT id,year,vin,carModel,condition,licenseState,regNum,stage,vehicleID,paintCode,dateOfInvoice," +
"bodyStyle,manufacturer, customerID FROM invoices LIMIT 100 OFFSET (SELECT COUNT(*) FROM invoices)-%d", indexStart));
int id;
String customerID;
String year;
String vin;
String carModel;
String condition;
String licenseState;
String regNum;
String stage;
String vehicleID;
String paintCode;
String dateOfInvoice;
String bodyStyle;
String manufacturer;
c.setAutoCommit(false);
while (rs.next()) {
id = rs.getInt(1);
year = rs.getString(2);
vin = rs.getString(3);
carModel = rs.getString(4);
condition = rs.getString(5);
licenseState = rs.getString(6);
regNum = rs.getString(7);
stage = rs.getString(8);
vehicleID = rs.getString(9);
paintCode = rs.getString(10);
dateOfInvoice = rs.getString(11);
bodyStyle = rs.getString(12);
manufacturer = rs.getString(13);
customerID = rs.getString(14);
// System.out.println(String.format("ID: %d , CustomerID: %s Year: %s, Vin: %s, \ncarModel %s, condition: %s, licenseState: %s \n" +
// "regNum: %s, stage: %s vehicleID: %s, paintCode: %s, dateOfInvoice: %s, bodyStyle:%s", id, customerID, year, vin, carModel
// , condition, licenseState, regNum, stage, vehicleID, paintCode, dateOfInvoice, bodyStyle));
//add to invoice list.
invoices.add(new invoiceOBJ(id,
carModel, manufacturer,
vin, condition, licenseState,
regNum, stage, vehicleID, paintCode,
bodyStyle, year, dateOfInvoice, findCustomer(customerID)));
// System.out.println("added A customer");
}
stmt.close();
rs.close();
c.close();
//System.out.println("load complete..");
} catch (Exception e) {
e.printStackTrace();
}
// System.out.println(System.currentTimeMillis() - time);
return invoices;
}
public HashMap<String, String> findCustomer(String id) {
String sql = String.format("SELECT firstName, lastName,id, date FROM customers WHERE id=%s", id);
HashMap<String, String> customerData = new HashMap<>();
try {
Statement stmt = c.createStatement();
ResultSet data = stmt.executeQuery(sql);
customerData.put("firstName", data.getString(1));
customerData.put("lastName", data.getString(2));
customerData.put("date", data.getString(4));
customerData.put("id", data.getString(3));
stmt.close();
data.close();
} catch (Exception e) {
e.printStackTrace();
}
return customerData;
}
public void disconnect() {
try {
c.close();
stmt.close();
} catch (Exception e) {
e.printStackTrace();
}
}
PS这是我的第一次尝试,也是我第一次使用SQL,所以任何额外的解释都将不胜感激!谢谢!
编辑:我已经阅读过的一些资源:
Mysql 中更快的分页 - 为什么 Order By With Limit 和 Offset 很慢?
不知道这些是否好/相关,只是为了提供更多细节。
图像中的功能:
https://imgur.com/a/pczeCSO:之前
https://imgur.com/a/kZT3l9C:+100更多/下一张发票。
解决方案
推荐阅读
- reactjs - 如何在 useEffect 挂钩中设置状态?
- node.js - WebStorm/SQLite 是否有特定配置
- html - 我的链接按钮不起作用
- excel - 是否有将逗号分隔列表分隔为值列的 Power Query 函数?
- python - awk的python替代品?
- javascript - 我的 sendtowhatsapp.js 不执行我的表单
- arrays - 使用一个数组值访问另一个数组元素 Matlab
- c++ - 强制转换为 bool 是检查是否存在与键匹配的 unordered_map 值的有效方法吗?C++
- python - 给定一个多嵌套的 Python 函数,如何在一些任意嵌套的函数中一直访问闭包变量?
- leaflet - Leaflet - geoJSON multipolygon - bindPopup 与 bindTooltip