目前我正在使用datanucleus 4.0.2进行项目。 在一些表中,我有多达一百万行,这通常不是数据库处理的问题。
然而,当datanucleus获取所有依赖元素时,它将生成如下所示的查询:
SELECT
'my.com.CHILD_TABLE' AS NUCLEUS_TYPE,
`CHILD_TABLE`.`ID` # And alot of more fields
FROM
`CHILD_TABLE`
WHERE
EXISTS( SELECT DISTINCT
'my.com.MIDDLE_TABLE' AS NUCLEUS_TYPE,
`MIDDLE_TABLE`.`ID`
FROM
`MIDDLE_TABLE`
INNER JOIN
`FIRST_TABLE` ON `MIDDLE_TABLE`.`MIDDLE_PARENT_ID_OID` = `FIRST_TABLE`.`ID`
WHERE
`FIRST_TABLE`.`TABLE_OWNER_ID_OID` = 5057520
AND `CHILD_TABLE`.`PARENT_ID_OID` = `MIDDLE_TABLE`.`ID`)
出于某种原因,mysql需要扫描子表中的所有100万行。 (这可能是查询执行计划程序错误)
将其转换为此表格
SELECT
'my.com.CHILD_TABLE' AS NUCLEUS_TYPE,
`CHILD_TABLE`.`ID`
FROM
`CHILD_TABLE`
INNER JOIN `MIDDLE_TABLE`
ON `CHILD_TABLE`.`PARENT_ID_OID` = `MIDDLE_TABLE`.`ID`
INNER JOIN
`FIRST_TABLE` ON `MIDDLE_TABLE`.`MIDDLE_PARENT_ID_OID` = `FIRST_TABLE`.`ID`
WHERE
`FIRST_TABLE`.`TABLE_OWNER_ID_OID` = 5057520
给出神奇的结果,只需要扫描9行或类似的行。
是否可以控制datanucleus如何生成这些查询?
聚苯乙烯。我找到了一个相关的帖子,在存在http://solutionfactor.net/blog/2011/11/06/mysql-inner-join-vs-exists-may-yield-better-performance/
时用mysql解释问题使用某些代码更新了问题 以下是实体关系的设置方式:
@PersistenceCapable(detachable = "true", identityType = IdentityType.APPLICATION)
class ChildTable {
@PrimaryKey
private Long id;
MiddleTable middleTable;
// More fields
}
@PersistenceCapable(detachable = "true", identityType = IdentityType.APPLICATION)
class MiddleTable {
@PrimaryKey
private Long id;
ParentTable parentTable;
@Persistent(mappedBy="middleTable", defaultFetchGroup="true")
private Set<ChildTable> children;
}
@PersistenceCapable(detachable = "true", identityType = IdentityType.APPLICATION)
class ParentTable {
@PrimaryKey
private Long id;
MasterTable masterTable;
@Persistent(mappedBy="parentTable")
private Set<MiddleTable> children;
}
// Master table code is left out for brewety, same set up
Query query = pm.newQuery(MiddleTable.class);
Collection<MiddleTable> entitySet;
try {
query.setFilter("parentTable.masterTable == :masterTable");
entitySet = (Collection<MiddleTable>) query.execute(masterTable);
}
finally {
query.closeAll();
}
基本上这里发生的是执行查询时datanucleus还将执行两个本机查询。 第一个效果很好。它看起来像我发布的第一个原始查询,除了EXISTS的东西。
启动第二个,因为子项位于默认的提取组中。这就是我想减少查询次数的方法。稍后将访问所有儿童。