我的数据库表(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
答案 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将提供此功能。