簡體   English   中英

與JDBC(h2數據庫)相比,使用hibernate進行長SQL查詢

[英]Long SQL query with hibernate compared to JDBC (h2 database)

我已經發布了一個相關的問題,但是我想在這里詢問更多詳細信息:

我使用休眠和以下代碼從應用程序中執行SQL查詢:

Query query = session.getNamedQuery("sql.namedquery.captureinfo");
Long t0 = System.currentTimeMillis();
List<Object[]> sqlList = query.list();
Long t1 = System.currentTimeMillis();
System.err.println("SQL query took" + (t1 - t0));

處理此查詢的時間約為6s。 我使用H2作為基礎數據庫。 命名查詢的定義如下:

<sql-query name="sql.namedquery.captureinfo">
<return-scalar column="eoid"                        type="int"/>
<return-scalar column="oid"                         type="int"/>
<return-scalar column="capture.obs_sys_id"          type="int"/>
<return-scalar column="capture.obs_mys_id"          type="int"/>
<return-scalar column="mid"                         type="int"/>
<return-scalar column="hdwr.type_hdwr"              type="string"/>
<return-scalar column="element_capture.description" type="string"/>
<return-scalar column="element_capture.dataf"       type="string"/>
<return-scalar column="geometrie.point"             type="materialized_blob"/>
<return-scalar column="geometrie.polygon"           type="materialized_blob"/>
<return-scalar column="element_capture.date_min"    type="date"/>
<return-scalar column="gid"                         type="int"/>
<return-scalar column="hdwr.nom"                    type="string"/>
select eo.id as eoid,o.id as oid,o.obs_sys_id,o.obs_mys_id,m.id as mid,m.type_hdwr,eo.description,eo.dataf,g.point,g.polygon,eo.date_min,g.id as gid,m.nom from element_capture eo left outer join geometrie g on eo.eo_geometrie_id = g.id left outer join hdwr m on eo.eo_hdwr_id = m.id left outer join capture o on eo.eo_capture_id = o.id
</sql-query>

使用用於H2的嵌入式SQL客戶端執行完全相同的查詢,它在不到一秒鍾的時間內執行。 我還直接使用JDBC進行了測試,以檢查開銷是否由JDBC驅動程序引起。 這是代碼:

package test;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class JDBCTest
{

    public static void main(String[] args) throws ClassNotFoundException, SQLException
    {

        Class.forName("org.h2.Driver");

        Connection connection = DriverManager.getConnection("jdbc:h2:data/mydatabase", "XXX", "YYY");
        Long start = System.currentTimeMillis();

        String request =
            "select eo.id as eoid,o.id as oid,o.obs_sys_id,o.obs_mys_id,m.id as mid,m.type_hdwr,eo.description,eo.dataf,g.point,g.polygon,eo.date_min,g.id as gid,m.nom from element_capture eo left outer join geometrie g on eo.eo_geometrie_id = g.id left outer join hdwr m on eo.eo_hdwr_id = m.id left outer join capture o on eo.eo_capture_id = o.id";
        PreparedStatement statement = connection.prepareStatement(request);

        ResultSet res = statement.executeQuery();
        while(res.next())
        {
            System.out.println(res.getInt(1) + "|" + res.getInt(2) + "|" + res.getInt(3) + "|" + res.getInt(4) + "|"
                + res.getInt(5) + "|" + res.getString(6) + "|" + res.getString(7) + "|" + res.getString(8) + "|"
                + res.getDate(11) + "|" + res.getInt(12) + "|" + res.getString(13));
            Blob a = res.getBlob(9);
            Blob b = res.getBlob(10);
            a.getBytes(0, (int)a.length()); // make sure to stream out the blob
            //b.getBytes(0, (int)b.length());  // commented out as b is null in every record

        }
        Long end = System.currentTimeMillis();
        System.out.println((end - start) + "ms");
        res.close();
        statement.close();
        connection.close();
    }
}

執行此代碼還需要大約一秒鍾的時間(包括在控制台中打印出結果,從數據庫中檢索到6398條記錄)。

因此,對於同一查詢,在休眠版本和JDBC版本之間會有相當大的開銷,我不理解。 我希望會有一點開銷,但是不會太多。 我啟用了休眠的詳細日志記錄,這是日志的開頭:

11:42:49,083 TRACE QueryPlanCache:200 - Located native-sql query plan in cache (select eo.id as eoid,o.id as oid,o.obs_sys_id,o.obs_mys_id,m.id as mid,m.type_hdwr,eo.description,eo.dataf,g.point,g.polygon,eo.date_min,g.id as gid,m.nom from element_capture eo left outer join geometrie g on eo.eo_geometrie_id = g.id left outer join hdwr m on eo.eo_hdwr_id = m.id left outer join capture o on eo.eo_capture_id = o.id)
11:42:49,112 TRACE ConnectionProxyHandler:110 - Handling invocation of connection method [prepareStatement]
11:42:49,113 DEBUG LogicalConnectionImpl:295 - Obtaining JDBC connection
11:42:49,115 TRACE DriverManagerConnectionProviderImpl:171 - Total checked-out connections: 1
11:42:49,116 DEBUG DriverManagerConnectionProviderImpl:192 - Opening new JDBC connection
11:42:49,121 DEBUG DriverManagerConnectionProviderImpl:202 - Created connection to: jdbc:h2:data/mydatabase, Isolation Level: 2
11:42:49,122 DEBUG LogicalConnectionImpl:301 - Obtained JDBC connection
11:42:49,142 DEBUG SQL:104 - select eo.id as eoid,o.id as oid,o.obs_sys_id,o.obs_mys_id,m.id as mid,m.type_hdwr,eo.description,eo.dataf,g.point,g.polygon,eo.date_min,g.id as gid,m.nom from element_capture eo left outer join geometrie g on eo.eo_geometrie_id = g.id left outer join hdwr m on eo.eo_hdwr_id = m.id left outer join capture o on eo.eo_capture_id = o.id
11:42:49,144 TRACE JdbcResourceRegistryImpl:65 - Registering statement [org.hibernate.engine.jdbc.internal.proxy.PreparedStatementProxyHandler@bf831db[valid=true]]
11:42:49,146 TRACE JdbcResourceRegistryImpl:75 - Registering last query statement [org.hibernate.engine.jdbc.internal.proxy.PreparedStatementProxyHandler@bf831db[valid=true]]
11:42:49,146 TRACE AbstractStatementProxyHandler:88 - Handling invocation of statement method [getWrappedObject]
11:42:49,147 TRACE JdbcResourceRegistryImpl:75 - Registering last query statement [prep3: select eo.id as eoid,o.id as oid,o.obs_sys_id,o.obs_mys_id,m.id as mid,m.type_hdwr,eo.description,eo.dataf,g.point,g.polygon,eo.date_min,g.id as gid,m.nom from element_capture eo left outer join geometrie g on eo.eo_geometrie_id = g.id left outer join hdwr m on eo.eo_hdwr_id = m.id left outer join capture o on eo.eo_capture_id = o.id]
11:42:49,148 TRACE Loader:1798 - Bound [1] parameters total
11:42:49,148 TRACE AbstractStatementProxyHandler:88 - Handling invocation of statement method [executeQuery]
11:42:53,537 TRACE JdbcResourceRegistryImpl:118 - Registering result set [org.hibernate.engine.jdbc.internal.proxy.ResultSetProxyHandler@42ea7f9f[valid=true]]
11:42:53,538 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getStatement]
11:42:53,540 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getStatement]
11:42:53,540 TRACE Loader:870 - Processing result set
11:42:53,541 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [next]
11:42:53,542 DEBUG Loader:873 - Result set row: 0
11:42:53,544 DEBUG Loader:1377 - Result row: 
11:42:53,545 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,549 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,550 TRACE BasicExtractor:72 - Found [-6398] as column [eoid]
11:42:53,551 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,552 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,553 TRACE BasicExtractor:72 - Found [-6398] as column [oid]
11:42:53,554 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,555 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,556 TRACE BasicExtractor:72 - Found [-14] as column [capture.obs_sys_id]
11:42:53,557 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,558 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,558 TRACE BasicExtractor:72 - Found [13] as column [capture.obs_mys_id]
11:42:53,559 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,560 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,560 TRACE BasicExtractor:72 - Found [1] as column [mid]
11:42:53,561 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getString]
11:42:53,562 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,562 TRACE BasicExtractor:72 - Found [APN] as column [hdwr.type_hdwr]
11:42:53,563 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getString]
11:42:53,564 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,564 TRACE BasicExtractor:72 - Found [obsstatus=NON_VU;meta.filename=tap_1387464655536.zip] as column [element_capture.description]
11:42:53,565 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getString]
11:42:53,565 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,566 TRACE BasicExtractor:72 - Found [tap_1387464655536.jpg] as column [element_capture.dataf]
11:42:53,567 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getBlob]
11:42:53,590 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,591 TRACE BasicExtractor:72 - Found [[B@2dce2a8d] as column [geometrie.point]
11:42:53,592 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getBlob]
11:42:53,593 TRACE BasicExtractor:67 - Found [null] as column [geometrie.polygon]
11:42:53,596 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getDate]
11:42:53,598 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,599 TRACE BasicExtractor:72 - Found [2013-12-19] as column [element_capture.date_min]
11:42:53,600 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,602 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,603 TRACE BasicExtractor:72 - Found [-6412] as column [gid]
11:42:53,604 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getString]
11:42:53,605 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,606 TRACE BasicExtractor:72 - Found [TQ9GY] as column [hdwr.nom]
11:42:53,608 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [next]
11:42:53,609 DEBUG Loader:873 - Result set row: 1
11:42:53,610 DEBUG Loader:1377 - Result row: 
11:42:53,611 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,612 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,613 TRACE BasicExtractor:72 - Found [-6397] as column [eoid]
11:42:53,614 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,619 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,620 TRACE BasicExtractor:72 - Found [-6397] as column [oid]
11:42:53,621 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,623 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,624 TRACE BasicExtractor:72 - Found [-14] as column [capture.obs_sys_id]
11:42:53,625 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,626 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,627 TRACE BasicExtractor:72 - Found [13] as column [capture.obs_mys_id]
11:42:53,628 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,629 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,630 TRACE BasicExtractor:72 - Found [1] as column [mid]
11:42:53,631 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getString]
11:42:53,632 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,633 TRACE BasicExtractor:72 - Found [APN] as column [hdwr.type_hdwr]
11:42:53,634 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getString]
11:42:53,634 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,635 TRACE BasicExtractor:72 - Found [obsstatus=A_REVOIR;meta.filename=tap_1387464653290.zip] as column [element_capture.description]
11:42:53,636 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getString]
11:42:53,636 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,637 TRACE BasicExtractor:72 - Found [tap_1387464653290.jpg] as column [element_capture.dataf]
11:42:53,637 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getBlob]
11:42:53,639 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,639 TRACE BasicExtractor:72 - Found [[B@3f46a7e8] as column [geometrie.point]
11:42:53,640 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getBlob]
11:42:53,641 TRACE BasicExtractor:67 - Found [null] as column [geometrie.polygon]
11:42:53,642 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getDate]
11:42:53,644 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,645 TRACE BasicExtractor:72 - Found [2013-12-19] as column [element_capture.date_min]
11:42:53,646 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getInt]
11:42:53,647 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,647 TRACE BasicExtractor:72 - Found [-6411] as column [gid]
11:42:53,648 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [getString]
11:42:53,649 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [wasNull]
11:42:53,650 TRACE BasicExtractor:72 - Found [TQ9GY] as column [hdwr.nom]
11:42:53,650 TRACE AbstractResultSetProxyHandler:72 - Handling invocation of ResultSet method [next]
so on until  DEBUG Loader:873 - Result set row: 6397

如您所見,SQL查詢返回標量值,而不是實體,因此,由於實體管理,因此沒有開銷。 那么,在解析結果時由休眠執行的所有那些操作是否解釋了這種極端的開銷? 我認為,在命名查詢中為我的所有參數指定返回類型將通過不讓它猜測結果類型來簡化休眠作業。 我還能做些什么來加快冬眠的速度?

似乎僅僅為標量定義結果類型還不夠,並且休眠狀態解析結果集所產生的開銷仍然很大。 我專門為我的查詢設置了PassThroughResultTransformer,與JDBC查詢相比,它有效地加快了解析速度,從而使開銷略微增加。 下面是我的問題中的第一個代碼摘錄中的更改:

Query query = session.getNamedQuery("sql.namedquery.captureinfo");
query.setResultTransformer(PassThroughResultTransformer.INSTANCE);
Long t0 = System.currentTimeMillis();
List<Object[]> sqlList = query.list();
Long t1 = System.currentTimeMillis();
System.err.println("SQL query took" + (t1 - t0));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM