The conceptual procedure for processing requests:
1. FROM 2. WHERE 3. GROUP BY 4. HAVING 5. SELECT 6. ORDER BY
But this is just a conceptual order. In fact, the engine may decide to reorder offers. Here is the proof. Allows you to make 2 tables of 1,000,000 rows:
CREATE TABLE test1 (id INT IDENTITY(1, 1), name VARCHAR(10)) CREATE TABLE test2 (id INT IDENTITY(1, 1), name VARCHAR(10)) ;WITH cte AS(SELECT -1 + ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) d FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t1(n) CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t2(n) CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t3(n) CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t4(n) CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t5(n) CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t6(n)) INSERT INTO test1(name) SELECT 'a' FROM cte
Now run 2 queries:
SELECT * FROM dbo.test1 t1 JOIN dbo.test2 t2 ON t2.id = t1.id AND t2.id = 100 WHERE t1.id > 1 SELECT * FROM dbo.test1 t1 JOIN dbo.test2 t2 ON t2.id = t1.id WHERE t1.id = 1
The notification will first filter most of the lines in the join state, the second in where . Look at the prepared plans:
1 TableScan - Predicate: [Test]. [dbo]. [test2]. [id] as [t2]. [id] = (100)
2 TableScan - Predicate: [Test]. [dbo]. [test2]. [id] as [t2]. [id] = (1)
This means that in the first optimized query, it was first decided to evaluate the join condition for filtering strings, and secondly, it first evaluated the where clause.