我在后端服务中使用Java Spring boot,数据库是MSSql。
我正在开发一个执行数据聚合并返回结果的 API。返回结果后,我使用 java 代码对数据进行最终设置,然后将其作为响应发送。
如果我获取单月的数据,整个过程大约需要12秒。如果我选择 6 个月的数据,它将永远花费时间,并且永远不会回复我。
最初我使用 JPA,但后来我切换到本机查询方法,这减少了一些时间,但 12 秒对于 30 天的数据处理仍然很重要。我想减少花费的时间。
我想出了两件事
我的双手被束缚在数据库上,因为我无法从 MSSql 切换到任何其他数据库,如 NoSql 或任何其他数据库。 我需要关于缓存策略以及如何减少 API 响应时间的一些指导。
在我的 SQL 查询下面:
WITH DateRange AS (
SELECT DATEADD(DAY, n, :fromDate) AS date
FROM (
SELECT TOP (DATEDIFF(DAY, :fromDate, :toDate) + 1)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 AS n
FROM sys.columns
) AS Numbers
)
SELECT
FORMAT(d.date, 'MM/dd/yyyy') AS label,
ISNULL(SUM(abc.data1), 0) AS data1,
ISNULL(SUM(abc.data2), 0) AS data2,
ISNULL(SUM(abc.data3), 0) AS data3
FROM
DateRange d
LEFT JOIN ABC abc ON
CAST(abc.date AS DATE) = d.date
WHERE filtering1
AND filtering2
AND d.date >= :fromDate
AND d.date <= :toDate
GROUP BY
d.date
ORDER BY
d.date ASC;
我在@Query注释中使用nativeQuery=true的查询
在实体上我使用这 2 个注释
List<String> dateLabels = new ArrayList<>();
List<Integer> data1 = new ArrayList<>();
List<Integer> data2 = new ArrayList<>();
List<Integer> data3 = new ArrayList<>();
rawResults.forEach(result -> {
dateLabels.add((String) result[0]);
data1.add(((Number) result[1]).intValue());
data2.add(((Number) result[2]).intValue());
data3.add(((Number) result[3]).intValue());
});
非常感谢任何帮助。
Map<String, Integer[]> dateDataMap = new HashMap<>();
for (Object[] result : rawResults) {
String dateLabel = (String) result[0];
Integer data1Value = ((Number) result[1]).intValue();
Integer data2Value = ((Number) result[2]).intValue();
Integer data3Value = ((Number) result[3]).intValue();
dateDataMap.put(dateLabel, new Integer[]{data1Value, data2Value, data3Value});
}