Как этот SQL-запрос будет оцениваться механизмом запросов? - PullRequest
2 голосов
/ 22 мая 2009

Я играл с SQL-запросами, и мне пришло в голову - select x,y from table T.

Здесь x и y могут быть арифметическими выражениями, такими как 2.0 / 5.0 ИЛИ 1 + 2, результат имеет количество строк таблицы T, причем первый столбец имеет значение 2.0 / 5.0, то есть 0.444444, а второй столбец имеет значение 3.

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

Пожалуйста, исправьте мое понимание, если оно неверно - для запроса, который я указал, будет внутреннее отображение из моего запроса Q во внутреннее представление, которое эквивалентно представлению select * from table T. Затем для всех возвращаемых строк проецируется n чисел столбцов, где n - количество арифметических выражений, указанных в Q. И все строки для n столбцов будут иметь свои соответствующие оценки арифметических выражений.

ура

Ответы [ 6 ]

1 голос
/ 22 мая 2009

будет сканироваться, потому что нет предложения where. здесь сервера sql установлен showplan_all на

select 2.0/5.0,1+2 from YourTable                                                            
  |--Compute Scalar(DEFINE:([Expr1003]=(0.400000), [Expr1004]=(3)))                           
       |--Index Scan(OBJECT:([wppusdev].[dbo].[AP_Voucher].[YourTable_Index]))
1 голос
/ 22 мая 2009

Нет, выражения вычисляются только один раз (по крайней мере, в MS SQL Server).

Вы можете легко увидеть это, если сделаете:

select rand() from tableT

Все строки будут иметь одинаковое случайное число.

1 голос
/ 22 мая 2009

Скорее всего, это зависит от базы данных.

Если выражения, которые вы используете для x и y, были постоянными, то приличная база данных должна распознать это и выполнить вычисление только один раз и просто поместить значение в набор результатов.

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

В целом вы правы, вычислите виртуальную таблицу, описанную в предложении from, тогда я считаю, что применяются фильтры из предложения where, за которым следует предложение select.

0 голосов
/ 23 мая 2009

Решение о том, оценивает ли база данных функцию один раз для каждой строки. В Oracle вы можете выбрать dbms_random.random () из таблицы и получить разные числа для каждой строки. Это полезно, например, если вы хотите вернуть строки в случайном порядке.

0 голосов
/ 23 мая 2009

PostgreSQL сначала оценит выражение, а затем, скорее всего, выполнит последовательное сканирование таблицы. Кроме того, как упоминалось ранее, многие разновидности SQL имеют ключевое слово EXPLAIN, которое покажет вам, как, учитывая вашу текущую реализацию, будет оцениваться конкретный запрос.

0 голосов
/ 22 мая 2009

С точки зрения MS SQL ...

Может не совпадать с SELECT * FROM Table, потому что движок должен понимать, что ему фактически не нужны никакие столбцы из таблицы, поэтому он, скорее всего, выберет самый тонкий индекс в таблице и отсканирует его.

Фактические уравнения должны оцениваться только один раз, а затем использоваться как константа.

...