Using two statements, initializing the user-defined variable in a separate statement will be equivalent performance.
Instead of the SET
statement, we could do
SELECT @row : = 0
which would achieve the same result, assigning a value to the user-defined variable @row
. The difference would that MySQL needs to prepare a resultset to be returned to the client. We avoid that with the SET
statement, which doesn't return a resultset.
With two separate statement executions, there's the overhead of sending an extra statement: parsing tokens, syntax check, semantic check, ... and returning the status to the client. It's a small amount of overhead. We aren't going to notice it onesie-twosie.
So performance will be equivalent.
I strongly recommend ditching the oldschool comma syntax for join operation, and using the JOIN
keyword instead.
Consider the query:
SELECT t.foo
FROM r
CROSS
JOIN t
ORDER BY t.foo
What happens when the table r
is guaranteed to contain exactly one row?
The query is equivalent to:
SELECT t.foo
FROM t
ORDER BY t.foo
We can use a SELECT query in place of a table or view. Consider for example:
SELECT v.foo
FROM ( SELECT t.foo
FROM t
) v
Also consider what happens with this query:
SELECT @foo := 0
There is no FROM clause (or Oracle-style FROM dual
), so the query will return a single row. The expression in the SELECT list is evaluated... the constant value 0 is assigned to the user-defined variable @foo.
Consider this query:
SELECT 'bar'
FROM ( SELECT @foo := 0 ) r
Before the outer query runs, the SELECT inside the parens is executed. (MySQL calls it an "derived table" but more generically it's an inline view definition.) The net effect is that the constant 0 is assigned to the user-defined variable, and a single row is returned. So the outer query returns a single row.
If we understand that, we have what we need to understand what is happening here:
SELECT t.mycol
FROM ( SELECT @row := 0 ) r
CROSS
JOIN mytable t
ORDER
BY t.mycol
Inline view r
is evaluated, the SELECT returns a single row, the value 0
is assigned to user-defined variable @row
. Since r
is guaranteed to return a single row, we know that the Cartesian product (cross join) with mytable
will result in one row for each row in mytable
. Effectively yielding just a copy of mytable
.
To answer the question that wasn't asked:
The benefit of doing the initialization within the statement rather than a separate statement is that we now have a single statement that stands alone. It knocks out a dependency i.e. doesn't require a separate execution of a SET
statement to assign the user defined variable. Which also cuts out a roundtrip to the database to prepare and execute a separate statement.