Some performance optimization for get #2043

Merged
lunny merged 4 commits from lunny/slight_perf_improve into master 2021-09-07 08:03:08 +00:00
4 changed files with 40 additions and 29 deletions

View File

@ -92,8 +92,8 @@ func BenchmarkFindStruct(b *testing.B) {
_, err := testEngine.Insert(&v) _, err := testEngine.Insert(&v)
assert.NoError(b, err) assert.NoError(b, err)
b.StartTimer()
var mynames = make([]BenchmarkFindStruct, 0, 1) var mynames = make([]BenchmarkFindStruct, 0, 1)
b.StartTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
err := testEngine.Find(&mynames) err := testEngine.Find(&mynames)
b.StopTimer() b.StopTimer()

View File

@ -213,7 +213,7 @@ func TestUnscopeDelete(t *testing.T) {
cnt, err = testEngine.ID(1).Delete(&s) cnt, err = testEngine.ID(1).Delete(&s)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
assert.EqualValues(t, nowUnix, s.DeletedAt.Unix()) assert.LessOrEqual(t, int(s.DeletedAt.Unix()-nowUnix), 1)
var s1 UnscopeDeleteStruct var s1 UnscopeDeleteStruct
has, err := testEngine.ID(1).Get(&s1) has, err := testEngine.ID(1).Get(&s1)
@ -225,7 +225,7 @@ func TestUnscopeDelete(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, "test", s2.Name) assert.EqualValues(t, "test", s2.Name)
assert.EqualValues(t, nowUnix, s2.DeletedAt.Unix()) assert.LessOrEqual(t, int(s2.DeletedAt.Unix()-nowUnix), 1)
cnt, err = testEngine.ID(1).Unscoped().Delete(new(UnscopeDeleteStruct)) cnt, err = testEngine.ID(1).Unscoped().Delete(new(UnscopeDeleteStruct))
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -203,14 +203,42 @@ func (statement *Statement) GenCountSQL(beans ...interface{}) (string, []interfa
return sqlStr, append(statement.joinArgs, condArgs...), nil return sqlStr, append(statement.joinArgs, condArgs...), nil
} }
func (statement *Statement) fromBuilder() *strings.Builder {
var builder strings.Builder
var quote = statement.quote
var dialect = statement.dialect
builder.WriteString(" FROM ")
if dialect.URI().DBType == schemas.MSSQL && strings.Contains(statement.TableName(), "..") {
builder.WriteString(statement.TableName())
} else {
builder.WriteString(quote(statement.TableName()))
}
if statement.TableAlias != "" {
if dialect.URI().DBType == schemas.ORACLE {
builder.WriteString(" ")
} else {
builder.WriteString(" AS ")
}
builder.WriteString(quote(statement.TableAlias))
}
if statement.JoinStr != "" {
builder.WriteString(" ")
builder.WriteString(statement.JoinStr)
}
return &builder
}
func (statement *Statement) genSelectSQL(columnStr string, needLimit, needOrderBy bool) (string, []interface{}, error) { func (statement *Statement) genSelectSQL(columnStr string, needLimit, needOrderBy bool) (string, []interface{}, error) {
var ( var (
distinct string distinct string
dialect = statement.dialect dialect = statement.dialect
quote = statement.quote fromStr = statement.fromBuilder().String()
fromStr = " FROM "
top, mssqlCondi, whereStr string top, mssqlCondi, whereStr string
) )
if statement.IsDistinct && !strings.HasPrefix(columnStr, "count") { if statement.IsDistinct && !strings.HasPrefix(columnStr, "count") {
distinct = "DISTINCT " distinct = "DISTINCT "
} }
@ -220,24 +248,7 @@ func (statement *Statement) genSelectSQL(columnStr string, needLimit, needOrderB
return "", nil, err return "", nil, err
} }
if len(condSQL) > 0 { if len(condSQL) > 0 {
whereStr = " WHERE " + condSQL whereStr = fmt.Sprintf(" WHERE %s", condSQL)
}
if dialect.URI().DBType == schemas.MSSQL && strings.Contains(statement.TableName(), "..") {
fromStr += statement.TableName()
} else {
fromStr += quote(statement.TableName())
}
if statement.TableAlias != "" {
if dialect.URI().DBType == schemas.ORACLE {
fromStr += " " + quote(statement.TableAlias)
} else {
fromStr += " AS " + quote(statement.TableAlias)
}
}
if statement.JoinStr != "" {
fromStr = fmt.Sprintf("%v %v", fromStr, statement.JoinStr)
} }
pLimitN := statement.LimitN pLimitN := statement.LimitN
@ -266,20 +277,20 @@ func (statement *Statement) genSelectSQL(columnStr string, needLimit, needOrderB
} }
if statement.needTableName() { if statement.needTableName() {
if len(statement.TableAlias) > 0 { if len(statement.TableAlias) > 0 {
column = statement.TableAlias + "." + column column = fmt.Sprintf("%s.%s", statement.TableAlias, column)
} else { } else {
column = statement.TableName() + "." + column column = fmt.Sprintf("%s.%s", statement.TableName(), column)
} }
} }
var orderStr string var orderStr string
if needOrderBy && len(statement.OrderStr) > 0 { if needOrderBy && len(statement.OrderStr) > 0 {
orderStr = " ORDER BY " + statement.OrderStr orderStr = fmt.Sprintf(" ORDER BY %s", statement.OrderStr)
} }
var groupStr string var groupStr string
if len(statement.GroupByStr) > 0 { if len(statement.GroupByStr) > 0 {
groupStr = " GROUP BY " + statement.GroupByStr groupStr = fmt.Sprintf(" GROUP BY %s", statement.GroupByStr)
} }
mssqlCondi = fmt.Sprintf("(%s NOT IN (SELECT TOP %d %s%s%s%s%s))", mssqlCondi = fmt.Sprintf("(%s NOT IN (SELECT TOP %d %s%s%s%s%s))",
column, statement.Start, column, fromStr, whereStr, orderStr, groupStr) column, statement.Start, column, fromStr, whereStr, orderStr, groupStr)
@ -311,7 +322,7 @@ func (statement *Statement) genSelectSQL(columnStr string, needLimit, needOrderB
if pLimitN != nil { if pLimitN != nil {
fmt.Fprintf(&buf, " LIMIT %v OFFSET %v", *pLimitN, statement.Start) fmt.Fprintf(&buf, " LIMIT %v OFFSET %v", *pLimitN, statement.Start)
} else { } else {
fmt.Fprintf(&buf, "LIMIT 0 OFFSET %v", statement.Start) fmt.Fprintf(&buf, " LIMIT 0 OFFSET %v", statement.Start)
} }
} else if pLimitN != nil { } else if pLimitN != nil {
fmt.Fprint(&buf, " LIMIT ", *pLimitN) fmt.Fprint(&buf, " LIMIT ", *pLimitN)

View File

@ -308,7 +308,7 @@ func (statement *Statement) colName(col *schemas.Column, tableName string) strin
if len(statement.TableAlias) > 0 { if len(statement.TableAlias) > 0 {
nm = statement.TableAlias nm = statement.TableAlias
} }
return statement.quote(nm) + "." + statement.quote(col.Name) return fmt.Sprintf("%s.%s", statement.quote(nm), statement.quote(col.Name))
} }
return statement.quote(col.Name) return statement.quote(col.Name)
} }