Java TypedQuery比直接查询数据库慢得多

Java TypedQuery比直接查询数据库慢得多,java,hibernate,jpa,Java,Hibernate,Jpa,我有一个应用程序需要选择可能非常多的行(几十万到几百万行) 当我直接对我的数据库(Oracle)运行查询时,它会在9-10秒内返回,并选择4M行 当我执行与TypedQuery相同的SQL时,它会在5分钟后超时 我尝试过分页、hibernate scrollableresults、将查询设置为只读、禁用缓存,甚至尝试过nativeQuery,但似乎没有任何帮助 示例代码如下: StringBuffer sql = new StringBuffer(); sql.append("SELECT t

我有一个应用程序需要选择可能非常多的行(几十万到几百万行)

当我直接对我的数据库(Oracle)运行查询时,它会在9-10秒内返回,并选择4M行

当我执行与TypedQuery相同的SQL时,它会在5分钟后超时

我尝试过分页、hibernate scrollableresults、将查询设置为只读、禁用缓存,甚至尝试过nativeQuery,但似乎没有任何帮助

示例代码如下:

StringBuffer sql = new StringBuffer();
sql.append("SELECT t from TestResult t WHERE t.endDatetime >= ");
sql.append(getDateSelector(timestampStart));
sql.append(" AND t.endDatetime <= ");
sql.append(getDateSelector(timestampEnd));
sql.append(" ORDER BY t.nodeId, t.endDatetime DESC");

TypedQuery<TestResult> query = entityManager.createQuery(sql.toString(), TestResult.class);

testResults = query.getResultList();
stringbuffersql=newstringbuffer();
append(“从TestResult t中选择t,其中t.endDatetime>=”;
append(getDateSelector(timestampStart));
sql.append(“AND t.endDatetime=”);
append(getDateSelector(timestampStart));

append(“和t.endDatetime这是因为在Java中,当您在Oracle studio中尝试获取所有400万条记录时,studio为预防起见增加了限制(我估计只有50行左右?或者像mysql workbench中那样可能有1000行?)。如果您认为通过排序可以在9秒内获取400万条记录,那么我不买它


无论如何,无论出于何种原因,将4M引入应用程序都是相当糟糕的ide。您应该尝试移动“分析”"到数据库,或者重新考虑处理,以便一次只使用所有结果的一部分。这就是分页的用途。如果您确实想获取所有行,那么每次需要时您都必须等待5分钟。

我在此处没有看到分页,您创建查询而不是使用prepared语句的方式是噩梦般的分页举个例子。你说的直接是指通过某种Gui管理工作室,对吧?如果没有指定,很可能会在每个选择中添加限制,以解释时差。嗯,所以你对结果进行分页,但仍然在循环中获取4M记录?为什么?这将需要更长的时间。从你的描述中,我了解到获取例如100行需要5m的时间inutesIn SQLDeveloper当我添加a和rownum No时,它不会,因为这将是愚蠢的。唯一改变的是结果池thah必须进行排序,从而产生时间差。因此,排序越多,需要的时间就越多。仍然只提取50行。您的“基准测试”这仅仅是一个错误的观点,这或许可以解释我所看到的时间差异。
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public List<TestResult> iterateAllTestResults(String startDateTime, String endDateTime)
{
    int offset = 0;
    List<TestResult> allTestResults = new ArrayList<>();

    List<TestResult> testResults;
    while ((testResults = this.getAllTestResultsIterableHelper(offset, 100, startDateTime, endDateTime)).size() > 0)
    {
        allTestResults.addAll(testResults);
        offset += testResults.size();
    }

    return allTestResults;
}

private List<TestResult> getAllTestResultsIterableHelper(int offset, int max, String startDateTime, String endDateTime)
{

    try
    {
        Timestamp timestampStart = DateTimeFormatter.convertFormattedDateToTimestamp(startDateTime);
        Timestamp timestampEnd = DateTimeFormatter.convertFormattedDateToTimestamp(endDateTime);

        StringBuffer sql = new StringBuffer();
        sql.append("SELECT t from TestResult t WHERE t.endDatetime >= ");
        sql.append(getDateSelector(timestampStart));
        sql.append(" AND t.endDatetime <= ");
        sql.append(getDateSelector(timestampEnd));
        sql.append(" ORDER BY t.nodeId, t.endDatetime DESC");

        List<TestResult> results = entityManager.().createQuery(sql.toString(), TestResult.class).setFirstResult(offset).setMaxResults(max).getResultList();

        return results;
    }
    catch (Exception e)
    {
        // omitted
    }
}