Что логично читает в sql server? как уменьшить не логично?
Из всех моих поисков, направленных на ускорение запросов на сервере sql, источники утверждают, что для уменьшения логического чтения используется правильное предложение where. На самом деле мне нужно знать, как работают хранимые процедуры в SQL Server, когда он получил запрос от внешнего интерфейса и несколько советов, которых следует избегать в хранимых процедурах, а что нет.
2 ответа
Логическое чтение означает записи, которые вы читаете из базы данных. Давайте рассмотрим небольшой глупый пример:
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, то есть в памяти. Это также говорит нам о том, что физическое чтение чтения могут различаться для запроса, в то время как логические чтения остаются такими же, пока запрос и данные не изменены.)
Технический документ Microsoft, являющийся частью технической документации по устаревшему SQL Server 2000 (p387, изначально из архитектуры SQL Server (SQL Server 2000)), имеет хорошее определение:
Ввод-вывод из экземпляра SQL Server делится на логический и физический ввод-вывод. Логическое чтение происходит каждый раз, когда ядро базы данных запрашивает страницу из буферного кэша. Если страница в данный момент не находится в буферном кеше, то выполняется физическое чтение для чтения страницы в буферный кеш. Если страница в данный момент находится в кэше, физическое чтение не генерируется; буферный кеш просто использует страницу уже в памяти.
Таким образом, логическое чтение - это когда механизм запросов должен прочитать данные. Во-первых, это выглядит в памяти. Если страница уже находится в памяти SQL Server, она использует это. Если он не может найти его в памяти, то это вызывает физическое чтение, и страница данных читается с диска. По сути, логическое чтение без последующего физического чтения является "попаданием в кэш".
Буферный кеш (также известный как буферный пул) является основной рабочей памятью SQL Server для решения запросов. Когда вы устанавливаете объем памяти, который будет использовать 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, он полностью отбросит планирование запросов.