Is there any significant performance difference between Query and QueryRow in the sql package?

s there any significant performance difference between the

func (db *DB) Query(query string, args ...interface{}) (*Rows, error)

and the

func (db *DB) QueryRow(query string, args ...interface{}) *Row

in the "database/sql" package even if you have LIMIT 1; at the end of your query?

1 Like

The difference is the overhead of a function call (i.e., almost nothing, compared to sending a query to your database). QueryRow calls Query, and then wraps the results in an sql.Row.

Source:

// Query executes a query that returns rows, typically a SELECT.
func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
	return tx.QueryContext(context.Background(), query, args...)
}

// QueryRowContext executes a query that is expected to return at most one row.
// QueryRowContext always returns a non-nil value. Errors are deferred until
// Row's Scan method is called.
// If the query selects no rows, the *Row's Scan will return ErrNoRows.
// Otherwise, the *Row's Scan scans the first selected row and discards
// the rest.
func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row {
	rows, err := tx.QueryContext(ctx, query, args...)
	return &Row{rows: rows, err: err}
}

// QueryRow executes a query that is expected to return at most one row.
// QueryRow always returns a non-nil value. Errors are deferred until
// Row's Scan method is called.
// If the query selects no rows, the *Row's Scan will return ErrNoRows.
// Otherwise, the *Row's Scan scans the first selected row and discards
// the rest.
func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
	return tx.QueryRowContext(context.Background(), query, args...)
}

Refer: https://github.com/golang/go/blob/release-branch.go1.13/src/database/sql/sql.go#L2299-L2308

1 Like