diff --git a/internal/sqladapter/database.go b/internal/sqladapter/database.go
index 1b2575f48099b42f5cad80fbf8169d34ef1dfeee..32ed66775abff749a066cf2436fa7f5556d08e71 100644
--- a/internal/sqladapter/database.go
+++ b/internal/sqladapter/database.go
@@ -218,19 +218,29 @@ func (d *database) Collection(name string) db.Collection {
 
 // StatementExec compiles and executes a statement that does not return any
 // rows.
-func (d *database) StatementExec(stmt *exql.Statement, args ...interface{}) (sql.Result, error) {
+func (d *database) StatementExec(stmt *exql.Statement, args ...interface{}) (res sql.Result, err error) {
 	var query string
-	var err error
 
 	if db.Conf.LoggingEnabled() {
 		defer func(start time.Time) {
-			db.Log(&db.QueryStatus{
+
+			status := db.QueryStatus{
 				Query: query,
 				Args:  args,
 				Err:   err,
 				Start: start,
 				End:   time.Now(),
-			})
+			}
+
+			if rowsAffected, err := res.RowsAffected(); err == nil {
+				status.RowsAffected = &rowsAffected
+			}
+
+			if lastInsertId, err := res.LastInsertId(); err == nil {
+				status.LastInsertID = &lastInsertId
+			}
+
+			db.Log(&status)
 		}(time.Now())
 	}
 
@@ -240,10 +250,12 @@ func (d *database) StatementExec(stmt *exql.Statement, args ...interface{}) (sql
 	}
 
 	if execer, ok := d.PartialDatabase.(HasStatementExec); ok {
-		return execer.StatementExec(p, args...)
+		res, err = execer.StatementExec(p, args...)
+		return
 	}
 
-	return p.Exec(args...)
+	res, err = p.Exec(args...)
+	return
 }
 
 // StatementQuery compiles and executes a statement that returns rows.
diff --git a/logger.go b/logger.go
index a29c6292ef44f831741dfb0106ef5feae07d7d9c..f1b95f56340b318abaaa52908468e5df8157c1de 100644
--- a/logger.go
+++ b/logger.go
@@ -8,11 +8,23 @@ import (
 	"time"
 )
 
+const (
+	fmtLogQuery        = `Query:          %s`
+	fmtLogArgs         = `Arguments:      %#v`
+	fmtLogRowsAffected = `Rows affected:  %d`
+	fmtLogLastInsertId = `Last insert ID: %d`
+	fmtLogError        = `Error:          %v`
+	fmtLogTimeTaken    = `Time taken:     %0.5fs`
+)
+
 // QueryStatus represents a query after being executed.
 type QueryStatus struct {
 	SessID uint64
 	TxID   uint64
 
+	RowsAffected *int64
+	LastInsertID *int64
+
 	Query string
 	Args  []interface{}
 
@@ -55,6 +67,10 @@ type Logger interface {
 // Log sends a query status report to the configured logger.
 func Log(m *QueryStatus) {
 	if lg := Conf.Logger(); lg != nil {
+
+		m.Query = reInvisibleChars.ReplaceAllString(m.Query, ` `)
+		m.Query = strings.TrimSpace(m.Query)
+
 		lg.Log(m)
 		return
 	}
@@ -70,24 +86,28 @@ type defaultLogger struct {
 }
 
 func (lg *defaultLogger) Log(m *QueryStatus) {
-	m.Query = reInvisibleChars.ReplaceAllString(m.Query, ` `)
-	m.Query = strings.TrimSpace(m.Query)
-
-	s := make([]string, 0, 4)
+	s := make([]string, 0, 6)
 
 	if m.Query != "" {
-		s = append(s, fmt.Sprintf(`Q: %s`, m.Query))
+		s = append(s, fmt.Sprintf(fmtLogQuery, m.Query))
 	}
 
 	if len(m.Args) > 0 {
-		s = append(s, fmt.Sprintf(`A: %#v`, m.Args))
+		s = append(s, fmt.Sprintf(fmtLogArgs, m.Args))
+	}
+
+	if m.RowsAffected != nil {
+		s = append(s, fmt.Sprintf(fmtLogRowsAffected, *m.RowsAffected))
+	}
+	if m.LastInsertID != nil {
+		s = append(s, fmt.Sprintf(fmtLogLastInsertId, *m.LastInsertID))
 	}
 
 	if m.Err != nil {
-		s = append(s, fmt.Sprintf(`E: %q`, m.Err))
+		s = append(s, fmt.Sprintf(fmtLogError, m.Err))
 	}
 
-	s = append(s, fmt.Sprintf(`T: %0.5fs`, float64(m.End.UnixNano()-m.Start.UnixNano())/float64(1e9)))
+	s = append(s, fmt.Sprintf(fmtLogTimeTaken, float64(m.End.UnixNano()-m.Start.UnixNano())/float64(1e9)))
 
 	log.Printf("\n\t%s\n\n", strings.Join(s, "\n\t"))
 }