MS SQL - row size limit

strvt
Уже с Приветом
Posts: 342
Joined: 31 Jul 2001 09:01
Location: Minsk -> CT

MS SQL - row size limit

Post by strvt »

Господа, наткнулись тут на ограничение MS SQL сервера - не поддерживает "широких" таблиц.
Выдаёт вот такой warning:
"Warning: The table '...' has been created but its maximum row size (...) exceeds the maximum number of bytes per row (8060). INSERT or UPDATE of a row in this table will fail if the resulting row length exceeds 8060 bytes"
Это можно как-нибудь вылечить? Ну кроме как преобразованием больших строк из varchar в text (чего очень не хочется)?

Странная какая-то база данных всё-таки :(
IA
User avatar
Dmitry67
Уже с Приветом
Posts: 28294
Joined: 29 Aug 2000 09:01
Location: SPB --> Gloucester, MA, US --> SPB --> Paris

Post by Dmitry67 »

Вы пока НЕ НАТКНУЛИСЬ на это ограничение
То есть таблица создалась
Проблема возникнет если у вас в одной записи сойдутся очень длинные строки

Что можно сделать
* забыть про это (возможно если в спецификации клиента написано что под название единицы измерения м мкв см км надо отвести 255 символов на всякий случай. Сложение всех этих 'на всякий случай' часто дает превышение которое реально не стрельнет)
* подумать так ли необходимы unicode data types. Их тоже иногда вводят на всякий случай не думая

Если ограничение на самом деле стреляет то нет другого выхода как
* сделать некоторые поля text. Начаь с самого длинного, точнее самого длинного из тех по которым поиск
* разбить таблицу на две по колонкам сделав связку 1:1
Зарегистрированный нацпредатель, удостоверение N 19719876044787 от 22.09.2014
strvt
Уже с Приветом
Posts: 342
Joined: 31 Jul 2001 09:01
Location: Minsk -> CT

Post by strvt »

Dmitry67 wrote:Вы пока НЕ НАТКНУЛИСЬ на это ограничение
То есть таблица создалась
Проблема возникнет если у вас в одной записи сойдутся очень длинные строки

Это я понимаю. Хотя вот наш идиот DBA этого так испугался, что неговоря никому обрезал часть полей на половину. Вяснилось случайно и как обычно за неделю до большого релиза.
Dmitry67 wrote:Что можно сделать
* забыть про это (возможно если в спецификации клиента написано что под название единицы измерения м мкв см км надо отвести 255 символов на всякий случай. Сложение всех этих 'на всякий случай' часто дает превышение которое реально не стрельнет)

Это наш short term solution. Я подозреваю, что не стрельнёт никогда, потому как все проблемы из-за двух больших (4000) полей. То что они оба набьют под завязку - мловероятно. Но кто этих европейцев знает.
Dmitry67 wrote:* подумать так ли необходимы unicode data types. Их тоже иногда вводят на всякий случай не думая

varchar это я надеюсь не юникод?
Dmitry67 wrote:Если ограничение на самом деле стреляет то нет другого выхода как
* сделать некоторые поля text. Начаь с самого длинного, точнее самого длинного из тех по которым поиск

Это long term solution. Но у наших джавовских ребят какие-то напряги с работой с полями типа text.
Dmitry67 wrote:* разбить таблицу на две по колонкам сделав связку 1:1

Не, это несерьёзно.

Вообщем, спасибо. А я надеялся, что всё-таки найдется волшебная кнопка, которая удвоит размер страницы. :)
IA
User avatar
KVA
Уже с Приветом
Posts: 5347
Joined: 03 Feb 1999 10:01
Location: NJ, USA

Post by KVA »

Кстати, а почему в MS SQL этот row limit есть? Скорее всего только tengiz может что-то достоверно сказать по этому поводу.
User avatar
Win32nipuh
Уже с Приветом
Posts: 2489
Joined: 04 Feb 2002 10:01
Location: Слава Україні!

Post by Win32nipuh »

KVA wrote:Кстати, а почему в MS SQL этот row limit есть? Скорее всего только tengiz может что-то достоверно сказать по этому поводу.


Очень похоже на старый добрый размер страницы 8К.
User avatar
YellowMan
Уже с Приветом
Posts: 1099
Joined: 30 Sep 1999 09:01
Location: Bryansk,RUSSIA >> Dublin, Ireland

Post by YellowMan »

Про это написано в любой книге - чтобы не дробить страницу. Иначе Вам придеться на одну запись делать 2,3,4 чтения и велик шанс что последний кусок будет пустой страницей за исключением 1 байта.
Может дело еще и в адресации и еще в чем то - кто знает все детали ?
В любом случае проблем особых с этим нет - кто Вам сказал что две таблицы с отношением 1:1 - это несерьезно ? Вот то что у девелоперов проблемы с полем text - это действительно несерьезно...
Удачи@С.Смирнов
Merle
Уже с Приветом
Posts: 109
Joined: 26 Sep 2002 12:24

Post by Merle »

Именно он и есть, размер записи не может быть больше размера страницы, размер страницы - 8К.
Почему так? Подозреваю, что возни много с записью вылезающей за размеры страницы, а смысла в этом мало.
Поправят это дело в Юконе, размер страницы по прежнему 8к, но там, то что не влезло грохаться не будет, а будет заводиться еще одна страница и туда сваливаться остаток того, что не влезло. Очевидно, что для производительности это не подарок, зато не будет возмущенных воплей "А куда это у меня пол-строки делось?!". То есть, у "талантливого" разработчика появится еще один шанс нащупать ручной тормоз в сиквеле... :P
Dmitry67 писал(а):
* разбить таблицу на две по колонкам сделав связку 1:1

Не, это несерьёзно.

Почему? Это как раз самый разумный и правильный выход. Разбиваем таблицу на две мелких со связью 1:1, делаем view с именем оригинальной, большой таблицы, в которой две мелкие таблички объединяются и вешаем на эту view INSTEAD OF триггер, который распихивает все вставки и update'ы по мелким табличкам.
Работы на 15 минут, все внешние запросы ни о чем не подозревают и работают с view как с оригинальной большой таблицей, и нет ни малейшего риска потерять данные. Все довольны.
User avatar
KVA
Уже с Приветом
Posts: 5347
Joined: 03 Feb 1999 10:01
Location: NJ, USA

Post by KVA »

YellowMan wrote:Про это написано в любой книге - чтобы не дробить страницу.


"Не кочегары мы, не плотники ..." Теоретическим основами разработки баз данных не обучены. Так пописываем SQL иногда ... :mrgreen:

А как же Oracle с долблением страниц справляется? Или он немеренно на Windows тормозит?
User avatar
GlebZ
Уже с Приветом
Posts: 1152
Joined: 03 Jan 2002 10:01
Location: NJ --> MA

Post by GlebZ »

strvt wrote:
Dmitry67 wrote:* разбить таблицу на две по колонкам сделав связку 1:1

Не, это несерьёзно.

А таблица в 200 с лишком полей серьёзнее? Понаписали у нас тут индийские товарищи. Видимо слово нормализация они вспоминают только на интервью
:х
Водку? Водку буду!
User avatar
YellowMan
Уже с Приветом
Posts: 1099
Joined: 30 Sep 1999 09:01
Location: Bryansk,RUSSIA >> Dublin, Ireland

Post by YellowMan »

KVA wrote:А как же Oracle с долблением страниц справляется? Или он немеренно на Windows тормозит?


Мне бы тоже было бы интересно узнать - насколько я помню по обрывкам памяти там размер страницы задается при создании таблицы - может это и есть выход ?
Удачи@С.Смирнов
vc
Уже с Приветом
Posts: 664
Joined: 05 Jun 2002 01:11

Post by vc »

YellowMan wrote:
KVA wrote:А как же Oracle с долблением страниц справляется? Или он немеренно на Windows тормозит?


Мне бы тоже было бы интересно узнать - насколько я помню по обрывкам памяти там размер страницы задается при создании таблицы - может это и есть выход ?


In Oracle, maximum row size is (maximum number of columns times maximum VARCHAR lenghth):

1,000 x 4,000 = 4,000,000 bytes in length.

Since a typical block (page) size is 4/8/16K (defined during the DB creation), long rows span several blocks.


With LOBS, a row, in theory, can be 1,000 x 4gig in size. LOBs are of course stored in separate segments so the number is a little bit misleading.
User avatar
KVA
Уже с Приветом
Posts: 5347
Joined: 03 Feb 1999 10:01
Location: NJ, USA

Post by KVA »

vc wrote:In Oracle, maximum row size is (maximum number of columns times maximum VARCHAR lenghth):

1,000 x 4,000 = 4,000,000 bytes in length.


Нет ну это мы знаем. Вопрос в том почему то что для Oracle-а хорошо, то MS SQL-ю плохо? Как Oracle справляется с тем что row разползается на несколько страниц и без потери (?) прозводительности. И почему MS SQL не может того же самого.
8K
Уже с Приветом
Posts: 5552
Joined: 20 Mar 2001 10:01
Location: SFBA

Post by 8K »

KVA wrote:Как Oracle справляется с тем что row разползается на несколько страниц и без потери (?) прозводительности. И почему MS SQL не может того же самого.

MS SQL "много может, но мало ли что..." (ц)
Увидев друга, Портос вскрикнул от радости...
Merle
Уже с Приветом
Posts: 109
Joined: 26 Sep 2002 12:24

Post by Merle »

KVA wrote: Как Oracle справляется с тем что row разползается на несколько страниц и без потери (?) прозводительности. И почему MS SQL не может того же самого.

А почему Вы априори решили, что без потери? Теже принципы, те же проблемы. Если в Оракле одна запись оказывается больше размера страницы - это тоже не подарок.
User avatar
KVA
Уже с Приветом
Posts: 5347
Joined: 03 Feb 1999 10:01
Location: NJ, USA

Post by KVA »

Merle wrote:А почему Вы априори решили, что без потери? Теже принципы, те же проблемы. Если в Оракле одна запись оказывается больше размера страницы - это тоже не подарок.


Да я и не знаю, я просто спрашиваю. Но с другой стороны никто вроде не заявлял громко что Oracle на Windows уступает MS SQL в производительности из-за размера страниц. А раз не уступает, то и проблема не такая уж серьезная, а раз так, то почему есть ограничение в MS SQL.

В общем я не пытаюсь обидеть фанатов MS SQL. Просто кое-что непонятно. :)
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Post by tengiz »

KVA wrote:Да я и не знаю, я просто спрашиваю. Но с другой стороны никто вроде не заявлял громко что Oracle на Windows уступает MS SQL в производительности из-за размера страниц. А раз не уступает, то и проблема не такая уж серьезная, а раз так, то почему есть ограничение в MS SQL.

Ограничение на размер строки размером страницы даёт возможность использовать очень эффективную оптимизацию при сканировании диапазонов в индексе. В этом одно из заметных отличий MS SQL от Oracle, где такая оптимизация невозможна и поэтому там где MS SQL для выдачи сортированного набора просто сканирует индекс, Oracle делает чтение страниц в их реальном физическое порядке, а затем делает сортировку.
Cheers
User avatar
YellowMan
Уже с Приветом
Posts: 1099
Joined: 30 Sep 1999 09:01
Location: Bryansk,RUSSIA >> Dublin, Ireland

Post by YellowMan »

Tengiz, Вы так сказали будто бы этих заметных отличий мало и ширина таблицы одна из самых важных :)

KVA wrote:В общем я не пытаюсь обидеть фанатов MS SQL. Просто кое-что непонятно. :)


Да мы не фанаты - мы с ним работаем. Еще не хватало серверу молиться или у оптимизатора автограф просить :)
Удачи@С.Смирнов
User avatar
KVA
Уже с Приветом
Posts: 5347
Joined: 03 Feb 1999 10:01
Location: NJ, USA

Post by KVA »

Спасибо, Tengiz

Да мы не фанаты - мы с ним работаем. Еще не хватало серверу молиться или у оптимизатора автограф просить :)


Да кто его знает. Тут столько тем было. Чуть тронешь чью-нибудь любимую OS, compiler, DB, etc народ сразу рубаху на груди рвет и в драку лезет.
vc
Уже с Приветом
Posts: 664
Joined: 05 Jun 2002 01:11

Post by vc »

Hello Kemosabe. How's that tundra beastie shaping up ?

tengiz wrote:
KVA wrote:Да я и не знаю, я просто спрашиваю. Но с другой стороны никто вроде не заявлял громко что Oracle на Windows уступает MS SQL в производительности из-за размера страниц. А раз не уступает, то и проблема не такая уж серьезная, а раз так, то почему есть ограничение в MS SQL.

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


Some Microsoft resident Oracle guru must have misled you.

Consider this:

Code: Select all

SQL> create table t1 as select * from all_objects;

SQL> describe t1;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OWNER                                     NOT NULL VARCHAR2(30)
 OBJECT_NAME                               NOT NULL VARCHAR2(30)
 SUBOBJECT_NAME                                     VARCHAR2(30)
 OBJECT_ID                                 NOT NULL NUMBER
 DATA_OBJECT_ID                                     NUMBER
 OBJECT_TYPE                                        VARCHAR2(18)
 CREATED                                   NOT NULL DATE
 LAST_DDL_TIME                             NOT NULL DATE
 TIMESTAMP                                          VARCHAR2(19)
 STATUS                                             VARCHAR2(7)
 TEMPORARY                                          VARCHAR2(1)
 GENERATED                                          VARCHAR2(1)
 SECONDARY                                          VARCHAR2(1)


... here we sort:

SQL> select * from t1 where object_name between 'A' and 'C' order by object_name;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   SORT (ORDER BY)
   2    1     TABLE ACCESS (FULL) OF 'T1'

SQL> create index t1_idx on t1(object_name);

Index created.


... and here we don't:

SQL> select * from t1 where object_name between 'A' and 'C' order by object_name;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'T1'
   2    1     INDEX (RANGE SCAN) OF 'T1_IDX' (NON-UNIQUE)



Best regards.
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Post by tengiz »

vc wrote:Some Microsoft resident Oracle guru must have misled you.

И имя этого гуру - vc. Только он не местный :).

Напоминаю, что некоторое время назад мы подробнейшим образом разбирали, что как только предполагаемый объём сканированных данных превышает некоторый порог, Oracle предпочитает физическое чтение с последующей сортировкой. Причина - при сканировании диапазона индекса Oracle не может использовать readahead потому что для чтения цепочки страниц индекса он должен читать страницы по одной. SQL Server же умеет использовать внутренние страницы индекса для "глубокого" readahead.

Так как не иметь кластерного индекса для таблицы MS SQL - это исключение, то возможноть быстного чтения btree принципиальна с точки зрения обеспечения хорошей производительности длинных чтений.

Ваш эксперимент не имеет большого смысла без статистики физического IO в случае наличия или отсуствия индекса - если таблица содержит дюжину страниц, то это абсолютно ни о чём не говорит. Тем более, что в той дискусси Вы показывали примеры, показывающие совершенно противоположное поведение Oracle, когда если я правильно помню, при наличии индекса и агрерациии по ведущей колонке индекса, Oracle делал физическое чтение, сортировку а затем аргерацию.
Cheers
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Post by tengiz »

YellowMan wrote:Tengiz, Вы так сказали будто бы этих заметных отличий мало и ширина таблицы одна из самых важных :)

:)

Дело не в ширине страницы - дело в том, чтобы всю строку уложить в страницу, чтобы для чтения целой строки не приходилось прыгать по цепочке страниц, составляющих одну строку - простые реализации таких цепочек не позволяют делать предварительную выборку. Вплоть до SQL Server 2000 ограничение на размер строки не особенно тревожило подавляющее большинство пользователей. Как только начнёт всерьёз тревожить - вот тогда посмотрим.
Cheers
vc
Уже с Приветом
Posts: 664
Joined: 05 Jun 2002 01:11

Post by vc »

tengiz wrote:
vc wrote:Some Microsoft resident Oracle guru must have misled you.

И имя этого гуру - vc. Только он не местный :).

Напоминаю, что некоторое время назад мы подробнейшим образом разбирали, что как только предполагаемый объём сканированных данных превышает некоторый порог, Oracle предпочитает физическое чтение с последующей сортировкой. Причина - при сканировании диапазона индекса Oracle не может использовать readahead потому что для чтения цепочки страниц индекса он должен читать страницы по одной. SQL Server же умеет использовать внутренние страницы индекса для "глубокого" readahead.


Well, yes, if the optimizer decides (based on statistics) that reading the table directly and then sorting is cheaper than index access (which is undoubtedly more heavy-weight than Microsoft's), then the choice is obvious, no argument about that.

tengiz wrote:Ваш эксперимент не имеет большого смысла без статистики физического IO в случае наличия или отсуствия индекса - если таблица содержит дюжину страниц, то это абсолютно ни о чём не говорит. Тем более, что в той дискусси Вы показывали примеры, показывающие совершенно противоположное поведение Oracle, когда если я правильно помню, при наличии индекса и агрерациии по ведущей колонке индекса, Oracle делал физическое чтение, сортировку а затем аргерацию.


Again, it's up to the optimizer what acces path to choose. I merely wanted to show that, in Oracle, such access path does exist and will be used if it's more beneficial than the alternative, all other things being equal. E.g., if a fraction of a multi-million row table is 'ordered by', then the index path will be chosen for the same reason as for my small table.


VC
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Post by tengiz »

vc,

What you say is sure related yet hardly relevant - разумеется оптимизатор Oracle в состоянии сделать план, который будет использовать индекс для сканирования относительно короткого диапазона ключей . Но я говорю о дргугом. Каждый логический оператор помещаемый в план оптимизатором имеет одну или более одной физическую реализацию и решение о том, какую конкретно использовать иногда делается уже на этапе выполнения (а не оптимизации). Физическая реализация оператора сканирования индекса в Oracle не имеет опции оптимизации предварительной выборки страниц индекса, тогда как SQL Server имеет - чему очень способствует ограничение на максимальный размер строки. Это всё, что я имел в виду.
Cheers
vc
Уже с Приветом
Posts: 664
Joined: 05 Jun 2002 01:11

Post by vc »

tengiz wrote:vc,

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


Here, we are in complete agreement...
User avatar
Dmitry67
Уже с Приветом
Posts: 28294
Joined: 29 Aug 2000 09:01
Location: SPB --> Gloucester, MA, US --> SPB --> Paris

Post by Dmitry67 »

Тем не менее это ограничение
Можно было бы просто не делать такой классной оптимизации для таблиц которые больше 8K
Но они бы работали как в Оракле
Зарегистрированный нацпредатель, удостоверение N 19719876044787 от 22.09.2014

Return to “Вопросы и новости IT”