Подтвердить что ты не робот

WHERE и JOIN порядок работы

Мой вопрос похож на этот порядок операций SQL, но с небольшим завихрением, поэтому я думаю, что справедливо спросить.

Я использую Teradata. И у меня есть 2 таблицы: table1, table2.

table1 имеет только столбец id.
table2 имеет следующие столбцы: id, val

Возможно, я ошибаюсь, но я думаю, что эти два утверждения дают одинаковые результаты.

Заявление 1.

SELECT table1.id, table2.val
FROM table1
INNER  JOIN table2
ON table1.id = table2.id
WHERE table2.val<100

Заявление 2.

SELECT table1.id, table3.val
FROM table1
INNER JOIN (
    SELECT *
    FROM table2
    WHERE val<100
)  table3
ON table1.id=table3.id

Мои вопросы: оптимизатор запросов будет достаточно умен, чтобы - сначала выполнить предложение WHERE, затем JOIN позже в Statement 1
- знать, что таблица 3 фактически не нужна в заявлении 2

Я новичок в SQL, поэтому, пожалуйста, просветите меня, если я что-то не понимаю.

4b9b3361

Ответ 1

это будет зависеть от многих факторов (размер таблицы, индекс, распределение ключей и т.д.), вы должны просто проверить план выполнения:

вы не говорите, какую базу данных, но вот несколько способов:
MySql EXPLAIN
SQL Server SET SHOWPLAN_ALL (Transact-SQL)
Планирование Oracle EXPLAIN

что объясняется в teradata?
Teradata Захват и сравнение планов быстрее с оформлением журнала Visual Explain и XML

Ответ 2

В зависимости от доступности статистики и индексов для рассматриваемых таблиц механизм перезаписи запроса в оптимизаторе может или не может сканировать Table2 для записей, где val < 100 перед сканированием Table1.

В определенных ситуациях на основе демографических данных, объединений, индексирования и статистики вы можете обнаружить, что оптимизатор не устраняет записи в плане запроса, когда вы считаете, что это необходимо. Даже если у вас есть производная таблица, такая как таковая в вашем примере. Вы можете заставить оптимизатор обрабатывать производную таблицу, просто разместив GROUP BY в вашей производной таблице. Затем оптимизатор должен разрешить агрегат GROUP BY, прежде чем он сможет рассмотреть возможность соединения между двумя таблицами в вашем примере.

SELECT table1.id, table3.val
FROM table1
INNER JOIN (
    SELECT table2.id, tabl2.val
    FROM table2
    WHERE val<100
    GROUP BY 1,2
)  table3
ON table1.id=table3.id

Это не означает, что ваш стандартный подход должен состоять в том, чтобы работать с этим через ваш код. Это, как правило, один из моих последних курортов, когда у меня есть план запросов, который просто не устраняет посторонние записи ранее достаточно в плане и приводит к тому, что слишком много данных сканируются и переносятся через различные файлы SPOOL. Это просто метод, который вы можете добавить в свой инструментарий, когда вы столкнетесь с такой ситуацией.

Механизм перезаписи запросов постоянно обновляется с одного выпуска до следующего, а сведения о том, как он работает, можно найти в Руководство по обработке транзакций SQL для Teradata 13.0.

Ответ 3

Если мне что-то не хватает, зачем вам нужно Table1?

Просто запрос Table2

Select id, val  
From table2  
WHERE val<100 

или вы используете строки в таблице1 в качестве фильтра? т.е. имеет ли таблица1 только подмножество идентификаторов в таблице2?

Если это так, тогда это тоже будет работать...

 Select id, val  
 From table2  
 Where val<100 
   And id In (Select id 
              From table1)

Но чтобы ответить на ваш вопрос, да, оптимизатор запросов должен быть достаточно интеллектуальным, чтобы определить лучший порядок, в котором нужно выполнить шаги, необходимые для перевода ваших логических инструкций в физический результат. Он использует статистические данные, которые база данных поддерживает в каждой таблице, чтобы определить, что делать (какой тип логики объединения использовать, например), как и любой порядок выполнения операций, чтобы минимизировать дисковые операции и затраты на обработку.

Ответ 4

Q1. сначала выполните предложение WHERE, затем JOIN позже в Statement 1

Дело в том, что если вы переключите порядок внутреннего соединения, то есть таблицу2 INNER JOIN table1, тогда я думаю, что предложение WHERE может быть обработано до операции JOIN на этапе подготовки. Тем не менее, я думаю, даже если вы не измените исходный запрос, оптимизатор должен иметь возможность переключать свой порядок, если он считает, что операция соединения будет слишком дорогостоящей с извлечением всей строки, поэтому сначала будет применяться WHERE. Просто думаю.

Q2. что таблица 3 на самом деле не нужна в заявлении 2

Teradata будет интерпретировать ваш второй запрос таким образом, чтобы производная таблица была необходима, поэтому она будет поддерживать обработку таблицы 3.