2015-04-19 69 views
1

说我有两个表 :正在运行多个'select where id = ...'比运行单个'select where id in(...)'更糟?

ID  ATTRIBUTE 
------ ----------- 
1  'FOO' 
2  'BAR' 
4  'BIZZ' 

ID  ATTRIBUTE2 
------ ----------- 
1  'FOO2' 
2  'BAR2' 
3  'BIZZ2' 

现在我想获取所有这些属性。我有两种方法可以做到这一点,我可以一次查询两个表,一个ID,或者我可以查询两个表中的所有ID,并通过结果集提取属性。

选项1:

List<MyObj> myObjs = new ArrayList<MyObj>(); 
for (int i = 1; i<5; i++) 
{ 
    String sql1 = "select attribute from table1 where id = ?"; 
    String sql2 = "select attribute2 from table2 where id = ?"; 
    PreparedStatement ps = conn.prepareStatement(sql); 
    ps.setInt(1, i); 
    PreparedStatement ps2 = conn.prepareStatement(sql2); 
    ps2.setInt(1,i); 

    ResultSet rs1 = ps.executeQuery(); 
    ResultSet rs2 = ps2.executeQuery(); 

    myObjs.add(new MyObj(i, rs1.getString("attribute1"), rs2.getString("attribute2")); 
    //No null handling but. 

} 

选项2:

String sql1 = "select id, attribute from table1 where id in (?)"; 
    String sql2 = "select id, attribute2 from table2 where id in (?)"; 
    PreparedStatement ps = conn.prepareStatement(sql); 
    ps.setArray(1, new ArrayList<Integer>(1,2,3,4,5); 
    PreparedStatement ps2 = conn.prepareStatement(sql2); 
    ps2.setArray(1, new ArrayList<Integer>(1,2,3,4,5); 

    ResultSet rs1 = ps.executeQuery(); 
    ResultSet rs2 = ps2.executeQuery(); 

    Hashmap<Integer,MyObj> myObjs = new HashMap<Integer, MyObj>(); 
    while (rs.next()) 
      { 
      myOjbs.add(rs.getInt("id")), new MyObj(rs.getInt("id"), rs.getString("attribute"))); 
      } 


    while (rs2.next()) 
     { 
       myObjs.get(rs2.getInt("id")).setAttribute2(rs2.getString("attribute2")) 
     } 

选项1似乎用于处理场景中的一个属性可能会丢失简单得多。但是,重复的SQL调用可能会重复数百万次。选项2的SQL调用较少,但需要处理列表可能不同步的情况。

问题是 - 这些解决方案之一显然是错的吗?

回答

0

如果你想获取ID,属性对,然后用一个查询:

select id, attribute from table1 where id in (?) 
union all 
select id, attribute2 from table2 where id in (?) 

虽然最佳答案的性能问题是“你的数据试试您的系统上,并看看会发生什么”,有一些指导方针。较少的查询通常更好,因为将数据导入和导出数据库存在开销。

1

选项1假定两次查询都会在每次执行时返回结果。选项2假定第二个查询返回的每一行都将对应于第一个查询返回的一行。这些都不是完全安全的假设。至少在处理查询结果时,您的Java代码应该检查这些条件,以便处理此类问题和/或在必要时进行优雅的释放。

即便如此,选项2可能比选项1更有效,但即使选项2似乎也没有机会利用数据库的功能。为什么不通过一个查询返回所有数据?这可能是这样的:

select t1.id, t1.attribute, t2.attribute2 
from table1 t1 join table2 t2 on t2.id = t1.id 
where t1.id in (?) 

这需要的一些问题,我通过确保既是attribute1attribute2返回的每个行指出照顾。它将不返回任何id没有行,也没有。如果您想诊断某些id s缺少一个属性或另一个属性的情况,则将该查询中的(内部)连接替换为外部连接的其中一种风格将产生结果,该结果通知关于仅两个中的一个属性给出了一个特定的id

注意,那就是,你不能使用此作业的union [all],因为那不会使你从attribute2值区分attribute1值,你的Java代码显示了你想做的事情。

相关问题