使用Hibernate查找包含100万条记录的表

时间:2012-07-24 14:07:58

标签: java database hibernate lookup

我的数据库表(geo ip lookup)有7列,其中2列构成<复合-ID取代。 现在,当我使用前2个coloumns查找值时,我需要 12-14秒来获取记录..

我的DAO代码如下所示:

String queryString = "from Igeo igeo where igeo.ip_from <= " + ip
            + "and igeo.ip_to >= " + ip;

    Query q = session.createQuery(queryString);
    List<Igeo> igeoList = q.list();

    if(igeoList.size() > 0){
        Igeo igeo = igeoList.get(0);

        ISP = igeo.getIsp();
        ...
        ...         
    }

* Igeo = java represnting表中的类

**当ip位于composite-id列的值之间时,将获取记录,例如

ip_from = 1; ip_to = 3; ip = 2;

所以将返回上面的行

此表仅用于读取记录,请建议我使用比上面更有效的queryString

2 个答案:

答案 0 :(得分:4)

首先删除hibernate并在查询浏览器中运行查询,并查看返回所需的时间。如果它需要相同的时间,那么它不是Hibernate。这是数据库的性能。确保将索引添加到两列ip_from和ip_to中。您还可以对查询执行查询计划,以查看数据库在底层运行的内容,并尝试优化查询计划。

我建议你不要在你的查询中使用连接。这会产生一个安全漏洞,允许来自外部各方的潜在SQL注入。最好使用以下内容:

Query q = session.createQuery("from Igeo igeo where igeo.from_ip >= ? and igeo.to_ip <= ?");
q.setString( 0, ip );
q.setString( 1, ip );

你也可以使用命名参数来缩短它。

答案 1 :(得分:0)

如果表IGeo不包含ip_from和ip_to的重叠范围,您可以试试这个

    String queryString = "FROM Igeo igeo"
        +  " WHERE igeo.ip_to >= " + ip
        +  " ORDER BY igeo.ip_to";

然后检查列表中的第一项(看看ip_from&lt; = ip)。

即使表格中包含ip_from,ip_to的重叠范围,我敢打赌上面的HQL会运行得更快。

<除了>你真的不应该像“ip”这样的原始字符串连接成HQL或SQL。它导致SQL注入攻击漏洞。请使用查询参数< /旁边>

另外,验证您的数据库是否在与Igeo.ip_to对应的列上有索引。

从您的描述中听起来,数据库的主键是Igeo.ip_from + IGeo.ip_to。如果ip_from和ip_to的值不重叠,那似乎没有规范化。主键只需要一列。如果您已选择将两列用作主键,则上述查询将通过添加单个索引而受益。

如果添加包含表中所有列的索引(从ip_to和ip_from开始),某些数据库的性能会更好。 (这使数据库能够通过仅访问索引来满足查询)。不确定MySQL是否可以在这种程度上进行优化,但我知道DB2和Oracle将提供此功能。

相关问题