Skip to content

Как думать подобно SQL Server: опасности оператора SELECT *

Пересказ статьи Brent Ozar. How to Think Like the SQL Server Engine: The Perils of SELECT *


В нашем последнем посте мы выполняли запрос с ORDER BY, но получали только один столбец в операторе SELECT:
SELECT Id 
FROM dbo.Users
WHERE LastAccessDate > '2014/07/01'
ORDER BY LastAccessDate;

Оценка стоимости составляла примерно $18 баксов запроса, поскольку SQL Server должен был:

  • Просканировать весь кластеризованный индекс, получая Id и LastAccessDate для каждой строки.

  • Сортировать этот список по LastAccessDate.


Давайте теперь поменяет только одну вещь в запросе - то, что мы выбираем:
SELECT 
FROM dbo.Users
WHERE LastAccessDate > '2014/07/01'
ORDER BY LastAccessDate;

И снова запустим оба запроса, чтобы получить их фактические планы выполнения:

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

Этот запрос плох с разных точек зрения.


SELECT может читать больше данных.
Я знаю, о чем вы думаете: оба запроса должны прочитать все 8-килобайтные страницы в таблице. Правильно? Нет - вернитесь к первой статье серии, когда была введена таблица Users. Я упомянул, что поле AboutMe, NVARCHAR(MAX), может быть настолько большим, что простирается вне строки - на 8-килобайтных страницах переполнения. Нашему запросу SELECT Id не нужно читать эти дополнительные страницы, в отличие от SELECT .

SELECT может сортировать больше данных.
SQL Server не может просто сортировать LastAccessDates - он сортирует строки целиком. Это означает, что ему потребуется больше времени процессора, больше памяти и чаще сбрасывать данных на диск, если оценки потребности в памяти неверны.

Вывод SELECT может потребовать больше времени. На это я всегда обращал внимание как администратор баз данных. Я бы говорил своим разработчикам: "Не выбирайте полей, которые вам не нужны, поскольку передача данных по сети потребует больше времени". Сейчас это меньшая из моих проблем: я все больше сосредотачиваюсь на времени процессора и выделении памяти под оператор сортировки.

Ваша первая подсказка о том, насколько плохо работает оператор сортировки SELECT
, 97% стоимости на сортировку. Но это не 97% той же самой стоимости запроса. Стоимость оригинального запроса составляла $18 баксов запроса, а проверка стоимости SELECT показывает почти ДЕВЯТЬСОТ БАКСОВ ЗАПРОСА.


Если бы баксы запроса были бы реальными долларами, я мог бы купить мой первый автомобиль за такие деньги.

Я ненавижу SELECT .


Речь не идет о звездочке как таковой - я говорю о ленивом получении всех столбцов, включая те, которые вам не нужны, а затем заставлять SQL Server сортировать их.

И то, что вы просто не включаете ORDER BY в ваш запрос, не означает, что вы не будете делать сортировку. Эрик писал о сортировках, которые проникают в ваш план, даже если вы не запрашиваете их.

В следующей статье мы вернемся к выбору только Id. Это не означает, что я собираюсь позволить моим разработчикам выбирать только Id и ничего более - я понимаю, что мы должны получить данные из базы данных. Однако когда я имею дело с настройкой запроса и вижу SELECT * (или ненормально большой список столбцов), я начинаю процесс настройки с вопроса: а действительно ли нам нужны все эти поля? Даже в Entity Framework вы можете выбрать нужные вам столбцы. Займет ли это немного больше вашего времени? Конечно - но это будет намного дешевле, чем стоимость лицензирования SQL Server CPU или стоимость Azure SQL DB, особенно когда ваше приложение начнет масштабироваться.

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

Автор не разрешил комментировать эту запись

Добавить комментарий

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options

Добавленные комментарии должны будут пройти модерацию прежде, чем будут показаны.