Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 缓存查询结果_Java_Sql_Spring_Postgresql - Fatal编程技术网

Java 缓存查询结果

Java 缓存查询结果,java,sql,spring,postgresql,Java,Sql,Spring,Postgresql,比如说,我们有一个高度可配置的报告系统,它允许用户选择列、过滤器和排序 所有这些配置都被转换为SQL,针对DB执行,然后用户看到他的报告并可以继续使用它。但是在每个操作上,比如排序,我们仍然构建一个查询 转换本身需要几毫秒,但对DB执行查询可能需要3-5秒(如果有大量并行执行,则最多需要20秒) 所以,我正在考虑添加某种缓存 目前,我看到三种方式: 添加一个表来缓存所有结果而不进行过滤,然后根据用户请求在Java端对其进行排序/过滤 每个结果添加一个表,但仍不包含筛选器。在这种情况下,我可以对数

比如说,我们有一个高度可配置的报告系统,它允许用户选择列、过滤器和排序

所有这些配置都被转换为SQL,针对DB执行,然后用户看到他的报告并可以继续使用它。但是在每个操作上,比如排序,我们仍然构建一个查询

转换本身需要几毫秒,但对DB执行查询可能需要3-5秒(如果有大量并行执行,则最多需要20秒)

所以,我正在考虑添加某种缓存

目前,我看到三种方式:

  • 添加一个表来缓存所有结果而不进行过滤,然后根据用户请求在Java端对其进行排序/过滤
  • 每个结果添加一个表,但仍不包含筛选器。在这种情况下,我可以对数量少得多的数据进行排序/筛选,但有超过10k个不同的报告,我认为创建10k个小表并不好
  • 与第一个选项类似,但LRU缓存位于Java端。我们可以在内存中存储2-3k报告结果。它通常比第一个选项更快,因为我们没有太多的并行用户,只有拥有大量报告的用户
  • 缓存失效将一天发生几次


    你认为什么是使它更快的最好方法?从您的角度来看,建议的解决方案有哪些利弊?如果您可以自由选择数据库和技术(Java堆栈),您会怎么做?

    好的,让我们确保我做对了

    有超过10万份不同的报告

    因此,对它们进行预计算和预缓存是没有意义的,它们必须按需生成

    行中没有太多数据,只有短字符串、日期和整数。在内存中获取它,甚至在内存中保存一段时间,成本并不高

    因此,缓存少量数据可以避免昂贵的查询,这很好

    添加一个表来缓存所有结果而不进行过滤,然后根据用户请求在Java端对其进行排序/过滤

    问题是,很可能每个报表查询都有不同的列和不同的名称,所以这不适合单个表,除非您使用类似JSON的格式,将每个缓存的结果行存储为JSON字典。。。在本例中,索引将是一个问题,即使您在JSON值内的字段上创建索引,如果您的许多报告中有大量不同的列名,您也需要大量索引

    闻起来像一罐虫子

    每个结果添加一个表,但仍不包含筛选器。在这种情况下,我可以对数量少得多的数据进行排序/筛选,但有超过10k个不同的报告,我认为创建10k个小表并不好

    优点:每个缓存表都可以有适当的列、数据类型和索引。缓存很容易失效,只需截断它。您可以将所有缓存表设置为UNLOGGED,以加快它们的速度。您可以使用以前使用的相同SQL查询对缓存结果执行所有额外的排序/过滤,因此这可能是编写代码的更简单选项。如果您只想获取部分结果,那么分页也很好。这将是将报告查询的结果复制到缓存中的最快选择,因为缓存已经在postgres中,所以不需要传输数据。您还可以将缓存存储在另一个驱动器/SSD上

    缺点:我听说大量表的主要问题是,如果文件系统在包含大量文件的目录上运行速度变慢。不过,这在现代文件系统上不应该是一个问题,而且我认为postgres本身根本不会被10k表所困扰

    这可能会使对信息模式的查询速度变慢,并且psql中的“\dt”之类的东西会有问题,因此缓存表最好隐藏在“缓存”模式中,这样它们就不会干扰。这样还可以更容易地从备份中排除它们

    它还将使用postgres服务器上的一些RAM来缓存缓存表,这取决于在线用户的数量

    我认为这值得做一点基准测试。创建一个模式,添加10k个表,看看是否有什么中断

    与第一个选项类似,但LRU缓存位于Java端。我们可以在内存中存储2-3k报告结果。它通常比第一个选项更快,因为我们没有太多的并行用户,只有拥有大量报告的用户

    这有点像是重新发明轮子,你需要在java中重新实现排序/过滤。。。加上缓存算法。。。米

    不过,还有其他选择:

    • 将缓存放在另一台计算机上的另一个数据库中。这可能是一个postgres实例或另一个数据库(可能需要重写某些查询)。只有当缓存占用了数据库中太多的RAM时,这才是有趣的

    • 将缓存放在web浏览器中,并使用javascript进行过滤/排序。这可能会更快,这取决于互联网连接的速度,这将减少服务器负载,但您必须编写大量javascript代码


    在我看来,您对大量的表持谨慎态度,谨慎是好的,但如果它运行良好,它确实是最简单的解决方案…

    我认为您需要编写一些代码,然后再回答一个更具体的问题。这个问题似乎与我们的关系更密切。如果您使用的是spring,然后是带有spring-data的@Cacheable注释。首先确保您的查询得到了优化。1 2 3中没有任何内容-我更希望查看spring缓存和Hibernate二级缓存使用数据库,然后将所有数据加载到内存中,并用Java重新实现数据库排序和筛选有什么意义?这怎么可能比本机数据库查询更快呢?@michalspring和Hibernate只允许缓存已经执行的查询。在Java中使用排序/过滤的目的是避免在DB端进行额外的过滤。在DB表中,我