Из всех моих поисков, чтобы ускорить запросы в sql-сервере, источники сказали, что они уменьшают логические чтения, используя предложение where. На самом деле мне нужно знать, как хранимые процедуры в рабочем потоке SQL Server обрабатываются, когда он получает запрос от внешнего интерфейса, и некоторые советы, которые следует избегать в хранимых процедурах, а какие нет.
Что логически читается на сервере sql? как уменьшить логику?
Ответ 1
Логическое чтение означает записи, которые вы читаете из базы данных. Возьмем небольшой, глупый пример:
select *
from
(
select *
from orders
where client = 1234
)
where item = 9876;
Здесь вы выбираете все заказы от клиента 1234. Затем вы берете их только для элемента 9876. Таким образом (если оптимизатор не видит этого и оптимизирует ваш запрос внутри себя) вы выбираете еще много записей на первом шаге, чем необходимо, Сократите логические чтения (и соответствующий большой промежуточный результат), применив оба критерия за один шаг:
select *
from orders
where client = 1234
and item = 9876;
(Это может также влиять на физические чтения, но необязательно. Например, первый запрос может получить доступ к 100 записям, а затем уменьшить это до 10, тогда как второе только прочитает эти 10. Но все 100 записей могут находиться в один дисковый блок, поэтому оба оператора считывают один блок диска, т.е. делают одно физическое чтение. Это может быть даже нулевое физическое чтение, кстати, в случае, если данные уже находятся в кэше dbms, то есть в памяти. что физические чтения могут варьироваться для запроса, в то время как логические чтения остаются теми же, если запрос и данные не изменяются.)
Ответ 2
Логическое чтение - это когда движок запроса должен читать данные, но он находит его уже в памяти SQL Server. Ему не нужно идти на диск. Если вам нужно извлечь данные с диска, это называется физическим чтением. Логическое чтение - это "кэш-кеш" в основном.
Однако говорить о том, что вам нужно делать, не видя запроса или не зная, что содержит таблица, и какие данные выглядят и как индексируются и организовываются данные, в принципе невозможно.
Большое количество логических считываний может быть не обязательно плохим - или, скорее, не обязательно предотвратимым. Что плохое из-за чрезмерного количества логических чтений. Если вы возвращаете 3 строки данных, но механизм запроса должен был сканировать 200 миллионов строк таблицы, чтобы сделать это, это будет очень медленным, и вы, вероятно, можете улучшить это, переписав запрос или добавив индекс.
Я бы начал с рассмотрения того, насколько сложны запросы в вашей хранимой процедуре. Примечательно, что я бы искал недостающие индексы. Если вы используете SELECT * FROM BigTable WHERE ProductDate >= '01/01/2014'
, я бы посмотрел, что есть индекс на ProductDate
. Однако, если вы используете SELECT * FROM BigTable ORDER BY ProductDate DESC
, то, да, индекс все равно поможет, но вам все равно придется возвращать весь набор данных, чтобы вы все равно должны были прочитать всю таблицу. Кроме того, логические чтения относятся к чтению страниц, поэтому, если вопрос ProductDate
равномерно распределен по диску, вам может потребоваться прочитать каждую страницу или почти каждую страницу.
Кроме того, может случиться так, что статистика на столе устарела. Если вы добавили 20 000 строк в таблицу, а SQL Server все еще думает, что там всего 2000, это будет полностью бросать планирование запросов.