Эффективность SQL-запросов подзапроса в select vs inner join - PullRequest
1 голос
/ 26 апреля 2019

У меня есть запрос со следующей структурой:

SELECT 
    Id,
    (SELECT COUNT(1) AS [A1]
     FROM [dbo].Table2 AS [Extent4]
     WHERE (Table1.Id = [Extent4].Id2)) AS [C1]
FROM TPO_User

Эта структура запроса обычно используется LINQ, а не следующей структурой:

SELECT Id
FROM Table1
LEFT OUTER JOIN
    (SELECT COUNT(1) AS [A1], [Extent4].Id2
     FROM [dbo].Table2 AS [Extent4]
     GROUP BY [Extent4].Id2) AS [C1] ON C1.Id2 = Table1.Id

Когда я сравниваю их, второй запрос имеет меньшую продолжительность. Может ли кто-нибудь объяснить точную разницу в выполнении такого запроса?

И стоит ли когда-либо иметь подзапрос в вашем операторе select вместо внутреннего соединения?

Ответы [ 2 ]

1 голос
/ 26 апреля 2019

Я ожидаю, что оба запроса будут иметь одинаковые характеристики производительности. При сравнении производительности вы должны быть уверены, что делаете их правильно. Например, выполнение двух запросов подряд не является хорошим сравнением, поскольку данные таблицы были загружены в память.

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

Я ожидаю, что коррелированный подзапрос будет иметь хорошую производительность с правильными индексами. Для вашего примера вы хотите индекс на Table2(Id2).

Какая производительность в целом выше? Что ж, просто разработать сценарии, в которых коррелированный подзапрос лучше. Например, если TPO_User имеет 1 строку, а Table2 - 1 000 000 строк, то коррелированный подзапрос будет лучше практически при любых обстоятельствах.

1 голос
/ 26 апреля 2019

В моем понимании:

  • предложение FROM является определением цели.
  • предложение SELECT является определением проекции (построчно).

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

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

Небольшой источник о порядке выполнения SQL-запроса: https://www.periscopedata.com/blog/sql-query-order-of-operations

Надеюсь, это поможет (и не стесняйтесь, чтобы люди поправили меня, если я ошибаюсь)

(И если я хорошо помню, теперь есть автоматическая функция для оптимизации запросов на сервере sql. Я думаю, что она сама исправит ошибки, не так ли?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...