forked from mirror/gorm
Improve preload speed (#2058)
All credits to @vanjapt who came up with this patch. Closes #1672
This commit is contained in:
parent
73e7561e20
commit
012d147974
|
@ -161,14 +161,17 @@ func (scope *Scope) handleHasOnePreload(field *Field, conditions []interface{})
|
||||||
)
|
)
|
||||||
|
|
||||||
if indirectScopeValue.Kind() == reflect.Slice {
|
if indirectScopeValue.Kind() == reflect.Slice {
|
||||||
|
foreignValuesToResults := make(map[string]reflect.Value)
|
||||||
|
for i := 0; i < resultsValue.Len(); i++ {
|
||||||
|
result := resultsValue.Index(i)
|
||||||
|
foreignValues := toString(getValueFromFields(result, relation.ForeignFieldNames))
|
||||||
|
foreignValuesToResults[foreignValues] = result
|
||||||
|
}
|
||||||
for j := 0; j < indirectScopeValue.Len(); j++ {
|
for j := 0; j < indirectScopeValue.Len(); j++ {
|
||||||
for i := 0; i < resultsValue.Len(); i++ {
|
indirectValue := indirect(indirectScopeValue.Index(j))
|
||||||
result := resultsValue.Index(i)
|
valueString := toString(getValueFromFields(indirectValue, relation.AssociationForeignFieldNames))
|
||||||
foreignValues := getValueFromFields(result, relation.ForeignFieldNames)
|
if result, found := foreignValuesToResults[valueString]; found {
|
||||||
if indirectValue := indirect(indirectScopeValue.Index(j)); equalAsString(getValueFromFields(indirectValue, relation.AssociationForeignFieldNames), foreignValues) {
|
indirectValue.FieldByName(field.Name).Set(result)
|
||||||
indirectValue.FieldByName(field.Name).Set(result)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -255,13 +258,21 @@ func (scope *Scope) handleBelongsToPreload(field *Field, conditions []interface{
|
||||||
indirectScopeValue = scope.IndirectValue()
|
indirectScopeValue = scope.IndirectValue()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
foreignFieldToObjects := make(map[string][]*reflect.Value)
|
||||||
|
if indirectScopeValue.Kind() == reflect.Slice {
|
||||||
|
for j := 0; j < indirectScopeValue.Len(); j++ {
|
||||||
|
object := indirect(indirectScopeValue.Index(j))
|
||||||
|
valueString := toString(getValueFromFields(object, relation.ForeignFieldNames))
|
||||||
|
foreignFieldToObjects[valueString] = append(foreignFieldToObjects[valueString], &object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i := 0; i < resultsValue.Len(); i++ {
|
for i := 0; i < resultsValue.Len(); i++ {
|
||||||
result := resultsValue.Index(i)
|
result := resultsValue.Index(i)
|
||||||
if indirectScopeValue.Kind() == reflect.Slice {
|
if indirectScopeValue.Kind() == reflect.Slice {
|
||||||
value := getValueFromFields(result, relation.AssociationForeignFieldNames)
|
valueString := toString(getValueFromFields(result, relation.AssociationForeignFieldNames))
|
||||||
for j := 0; j < indirectScopeValue.Len(); j++ {
|
if objects, found := foreignFieldToObjects[valueString]; found {
|
||||||
object := indirect(indirectScopeValue.Index(j))
|
for _, object := range objects {
|
||||||
if equalAsString(getValueFromFields(object, relation.ForeignFieldNames), value) {
|
|
||||||
object.FieldByName(field.Name).Set(result)
|
object.FieldByName(field.Name).Set(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue