虽然这看起来像是一个非常简单的问题,但我提出的唯一解决方案是,对于时间复杂度较低而不那么难看的任何建议?
我的应用程序是Java,并使用skife.jdbi
使用MS-sql DB进行检索。
假设我有Table
列A
,B
和C
,其中A
和B
构成主键。我希望在特定C
和A
的情况下检索B
。这很容易实现。但是,如果我的吞吐量要求非常高,那么我想分批制作这些Select
语句。我最终得到了类似下面的内容:
如果Set
Objects
的值为A
和B
,我会迭代列表,编译A
和B
的所有值。然后我运行SELECT A, B, C FROM tbl WHERE A IN :listOfAs AND B IN :listOfBs
之类的查询。然后我迭代查询的结果,通过比较A
和B
值将结果与原始对象匹配。这一切听起来都合理,但代码最终看起来像下面这看起来很难看并且不是最理想的?
class MyObject {
String A;
String B;
String C;
Object otherData;
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (!(other instanceof MyObject)) {
return false;
} else {
return A.equals(other.A) && B.equals(other.B);
}
}
@Override
public int hashCode() {
return 31 * A.hashCode() + B.hashCode();
}
}
// populates the of objects with their proper C value
void retrieveC(Set<MyObject> input) {
Set<String> aValues = new HashSet<>();
Set<String> bValues = new HashSet<>();
for (MyObject object : input) {
aValues.add(object.A);
bValues.add(object.B);
}
// the dao executes the query mentioned above, and returns a Set of
// MyObject instances with members A, B, and C populated from the results.
// Any results that do not contain a value for A, B, and C (which
// shouldn't exit) are filtered out by the dao.
Set<MyObject> results = dao.selectC(aValues, bValues);
// ewww... O(n^2)
for (MyObject object : input) {
boolean resultFound = false;
for (MyObject result : results) {
if (object.equals(result)) {
object.C = result.C;
resultFound = true;
break;
}
}
if (!resultFound) {
// handle this case
}
}
}
答案 0 :(得分:0)
我认为理想是
SELECT A, B, C FROM tbl WHERE A+' '+B IN :listOfAandBs
这不是listOfAs x listOfBs
(二次复杂度),而是listofAs . listOfBs
(线性,产品内)
答案 1 :(得分:0)
您可以转到fluent queries of JDBI。
,而不是DAO模式这样您就可以将批处理切换为流式传输。在JDBI页面给出的示例中,您将使用允许您在数据库返回结果时逐个将结果流式传输到接收器的内容来交换StringBuilder()。
如果可行,那当然取决于您的开发环境。