正在运行几个单一的选择id = ...'比运行单个'选择哪里的id(...)'?

时间:2015-04-19 23:22:02

标签: java sql

说我有两张桌子 :

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调用,但需要处理列表可能不同步的情况。

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

2 个答案:

答案 0 :(得分: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缺少一个属性或另一个属性的情况,那么用该外部联接的一种替换该查询中的(内部)联接将产生结果,该结果通知仅有的情况为特定id提供了两个属性之一。

另请注意,您无法使用union [all]执行此作业,因为这样您无法区分attribute1值与attribute2值,您的Java代码显示这些值你想做什么。

答案 1 :(得分:0)

如果要获取id,属性对,请使用一个查询:

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

虽然性能问题的最佳答案是“使用您的数据在您的系统上试一试,看看会发生什么”,但有一些指导原则。更少的查询通常会更好,因为将数据输入和输出数据库会产生开销。