Поля «вне строки» читаются при использовании кластерного индекса?

10

Я знаю, что при использовании VARCHAR(MAX)/NVARCHAR(MAX)столбцов данные сохраняются out of the row- в строке данных будет указатель на другое место, где хранится «большое значение».

У меня есть следующие вопросы:

  1. Каждое поле хранится out of the rowили только maxте?
  2. Если вы используете clustered indexтаблицу для чтения всей записи, считываются ли поля, хранящиеся вне строки, тоже?

VARCHAR (MAX) или NVARCHAR (MAX) рассматривается как «тип большого значения». Типы больших значений обычно хранятся вне строки. Это означает, что ...

gotqn
источник
2
Откуда взялась эта последняя цитата? Это не правильно.
Пол Уайт 9
@PaulWhite stackoverflow.com/a/148465/1080354
получил
3
Полный текст в оригинальной ветке MSDN (автор Jacob Sebastian) правильный. «Цитата» переполнения стека теряет совсем немного. Небольшая часть того, что вы цитировали выше, опускает все важные биты :)
Пол Уайт 9

Ответы:

13

Я знаю, что при использовании VARCHAR(MAX)/NVARCHAR(MAX)столбцов данные хранятся вне строки ...

На самом деле, это зависит от настройки large value types out of rowопции, которую можно установить с помощью sp_tableoption. Из документации :

BOL экстракт

По умолчанию для MAXзначений , которые будут храниться в построчно , до 8000 байт, если они подходят. Если вы не использовали sp_tableoptionдля изменения значения по умолчанию, ваши MAXданные, скорее всего, будут храниться в строке.

Тем не менее, не рекомендуется использовать MAXтипы данных для значений, которые никогда не будут превышать 8000 байт - вместо этого используйте тип не-MAX. Помимо всего прочего, производительность при работе с MAXтипами часто значительно ниже , поскольку SQL Server должен быть готов справляться с данными, размер которых может достигать 2 ГБ.

Каждое поле хранится вне строки или только максимальные?

Только MAXте. Кроме того, если ранее MAXстолбец строки был перемещен вне строки, затрагивается только этот столбец в этой строке. В строке он заменяется указателем на структуру вне строки LOB. Существуют также обстоятельства, когда столбцы, отличные от MAX, могут быть перемещены вне строки.

Если вы используете кластерный индекс таблицы для чтения всей записи, считываются ли поля, хранящиеся вне строки, тоже?

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

Пол Уайт 9
источник
Это всегда правда Scanning the clustered index traverses only in-row data.? Например, если вы хотите отобразить NVARCHAR(MAX)значения полей, как можно работать только с in-row-data(если значения хранятся вне строки)? Или когда вы используете кластерный индекс (потому что нет покрывающего индекса), но вы не собираетесь workиспользовать NVARCHAR(MAX)поле, SQL Server достаточно умен, чтобы это увидеть и пропустить поиск out-of-rowданных?
получил
Спасибо за ответ. Итак, наконец, если у вас есть два столбца - intи nvarchar(max)вы выбираете только intстолбец, SQL-сервер не тратит ресурсы readна out-of-rowданные, так как знает, что вы не собираетесь их использовать?
получил
Большое спасибо. Это очень мило. Кажется, что с помощью sp_tableoptionвы можете убрать из таблицы все, что не часто используется, чтобы уменьшить размер строки, когда выполняется много поисков / сканирований кластерного индекса.
получил
3
@gotqn Да. Вне строки был по умолчанию для старых типов больших объектов text, ntextи image. Конечно, вы также можете хранить большие типы в отдельной таблице.
Пол Уайт 9
4

Это поведение для хранения больших объектов может контролироваться настройкой таблицы:

exec sp_tableoption N'MyTable', 'large value types out of row', <'ON' or 'OFF'>

Ссылка в документации по SQL Server 2012 находится по адресу: http://msdn.microsoft.com/en-us/library/ms173530.aspx.

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

ДКП
источник
Спасибо, я правда не знала, что ты способен это контролировать.
получил