MS SQL - row size limit
-
- Уже с Приветом
- Posts: 342
- Joined: 31 Jul 2001 09:01
- Location: Minsk -> CT
MS SQL - row size limit
Господа, наткнулись тут на ограничение 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 (чего очень не хочется)?
Странная какая-то база данных всё-таки
Выдаёт вот такой 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
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
Вы пока НЕ НАТКНУЛИСЬ на это ограничение
То есть таблица создалась
Проблема возникнет если у вас в одной записи сойдутся очень длинные строки
Что можно сделать
* забыть про это (возможно если в спецификации клиента написано что под название единицы измерения м мкв см км надо отвести 255 символов на всякий случай. Сложение всех этих 'на всякий случай' часто дает превышение которое реально не стрельнет)
* подумать так ли необходимы unicode data types. Их тоже иногда вводят на всякий случай не думая
Если ограничение на самом деле стреляет то нет другого выхода как
* сделать некоторые поля text. Начаь с самого длинного, точнее самого длинного из тех по которым поиск
* разбить таблицу на две по колонкам сделав связку 1:1
То есть таблица создалась
Проблема возникнет если у вас в одной записи сойдутся очень длинные строки
Что можно сделать
* забыть про это (возможно если в спецификации клиента написано что под название единицы измерения м мкв см км надо отвести 255 символов на всякий случай. Сложение всех этих 'на всякий случай' часто дает превышение которое реально не стрельнет)
* подумать так ли необходимы unicode data types. Их тоже иногда вводят на всякий случай не думая
Если ограничение на самом деле стреляет то нет другого выхода как
* сделать некоторые поля text. Начаь с самого длинного, точнее самого длинного из тех по которым поиск
* разбить таблицу на две по колонкам сделав связку 1:1
Зарегистрированный нацпредатель, удостоверение N 19719876044787 от 22.09.2014
-
- Уже с Приветом
- Posts: 342
- Joined: 31 Jul 2001 09:01
- Location: Minsk -> CT
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
-
- Уже с Приветом
- Posts: 5347
- Joined: 03 Feb 1999 10:01
- Location: NJ, USA
-
- Уже с Приветом
- Posts: 2489
- Joined: 04 Feb 2002 10:01
- Location: Слава Україні!
-
- Уже с Приветом
- Posts: 1099
- Joined: 30 Sep 1999 09:01
- Location: Bryansk,RUSSIA >> Dublin, Ireland
Про это написано в любой книге - чтобы не дробить страницу. Иначе Вам придеться на одну запись делать 2,3,4 чтения и велик шанс что последний кусок будет пустой страницей за исключением 1 байта.
Может дело еще и в адресации и еще в чем то - кто знает все детали ?
В любом случае проблем особых с этим нет - кто Вам сказал что две таблицы с отношением 1:1 - это несерьезно ? Вот то что у девелоперов проблемы с полем text - это действительно несерьезно...
Может дело еще и в адресации и еще в чем то - кто знает все детали ?
В любом случае проблем особых с этим нет - кто Вам сказал что две таблицы с отношением 1:1 - это несерьезно ? Вот то что у девелоперов проблемы с полем text - это действительно несерьезно...
Удачи@С.Смирнов
-
- Уже с Приветом
- Posts: 109
- Joined: 26 Sep 2002 12:24
Именно он и есть, размер записи не может быть больше размера страницы, размер страницы - 8К.
Почему так? Подозреваю, что возни много с записью вылезающей за размеры страницы, а смысла в этом мало.
Поправят это дело в Юконе, размер страницы по прежнему 8к, но там, то что не влезло грохаться не будет, а будет заводиться еще одна страница и туда сваливаться остаток того, что не влезло. Очевидно, что для производительности это не подарок, зато не будет возмущенных воплей "А куда это у меня пол-строки делось?!". То есть, у "талантливого" разработчика появится еще один шанс нащупать ручной тормоз в сиквеле...
Почему? Это как раз самый разумный и правильный выход. Разбиваем таблицу на две мелких со связью 1:1, делаем view с именем оригинальной, большой таблицы, в которой две мелкие таблички объединяются и вешаем на эту view INSTEAD OF триггер, который распихивает все вставки и update'ы по мелким табличкам.
Работы на 15 минут, все внешние запросы ни о чем не подозревают и работают с view как с оригинальной большой таблицей, и нет ни малейшего риска потерять данные. Все довольны.
Почему так? Подозреваю, что возни много с записью вылезающей за размеры страницы, а смысла в этом мало.
Поправят это дело в Юконе, размер страницы по прежнему 8к, но там, то что не влезло грохаться не будет, а будет заводиться еще одна страница и туда сваливаться остаток того, что не влезло. Очевидно, что для производительности это не подарок, зато не будет возмущенных воплей "А куда это у меня пол-строки делось?!". То есть, у "талантливого" разработчика появится еще один шанс нащупать ручной тормоз в сиквеле...
Dmitry67 писал(а):
* разбить таблицу на две по колонкам сделав связку 1:1
Не, это несерьёзно.
Почему? Это как раз самый разумный и правильный выход. Разбиваем таблицу на две мелких со связью 1:1, делаем view с именем оригинальной, большой таблицы, в которой две мелкие таблички объединяются и вешаем на эту view INSTEAD OF триггер, который распихивает все вставки и update'ы по мелким табличкам.
Работы на 15 минут, все внешние запросы ни о чем не подозревают и работают с view как с оригинальной большой таблицей, и нет ни малейшего риска потерять данные. Все довольны.
-
- Уже с Приветом
- Posts: 5347
- Joined: 03 Feb 1999 10:01
- Location: NJ, USA
-
- Уже с Приветом
- Posts: 1152
- Joined: 03 Jan 2002 10:01
- Location: NJ --> MA
-
- Уже с Приветом
- Posts: 1099
- Joined: 30 Sep 1999 09:01
- Location: Bryansk,RUSSIA >> Dublin, Ireland
-
- Уже с Приветом
- Posts: 664
- Joined: 05 Jun 2002 01:11
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.
-
- Уже с Приветом
- Posts: 5347
- Joined: 03 Feb 1999 10:01
- Location: NJ, USA
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 не может того же самого.
-
- Уже с Приветом
- Posts: 5552
- Joined: 20 Mar 2001 10:01
- Location: SFBA
-
- Уже с Приветом
- Posts: 109
- Joined: 26 Sep 2002 12:24
KVA wrote: Как Oracle справляется с тем что row разползается на несколько страниц и без потери (?) прозводительности. И почему MS SQL не может того же самого.
А почему Вы априори решили, что без потери? Теже принципы, те же проблемы. Если в Оракле одна запись оказывается больше размера страницы - это тоже не подарок.
-
- Уже с Приветом
- Posts: 5347
- Joined: 03 Feb 1999 10:01
- Location: NJ, USA
Merle wrote:А почему Вы априори решили, что без потери? Теже принципы, те же проблемы. Если в Оракле одна запись оказывается больше размера страницы - это тоже не подарок.
Да я и не знаю, я просто спрашиваю. Но с другой стороны никто вроде не заявлял громко что Oracle на Windows уступает MS SQL в производительности из-за размера страниц. А раз не уступает, то и проблема не такая уж серьезная, а раз так, то почему есть ограничение в MS SQL.
В общем я не пытаюсь обидеть фанатов MS SQL. Просто кое-что непонятно.
-
- Уже с Приветом
- Posts: 4468
- Joined: 21 Sep 2000 09:01
- Location: Sammamish, WA
KVA wrote:Да я и не знаю, я просто спрашиваю. Но с другой стороны никто вроде не заявлял громко что Oracle на Windows уступает MS SQL в производительности из-за размера страниц. А раз не уступает, то и проблема не такая уж серьезная, а раз так, то почему есть ограничение в MS SQL.
Ограничение на размер строки размером страницы даёт возможность использовать очень эффективную оптимизацию при сканировании диапазонов в индексе. В этом одно из заметных отличий MS SQL от Oracle, где такая оптимизация невозможна и поэтому там где MS SQL для выдачи сортированного набора просто сканирует индекс, Oracle делает чтение страниц в их реальном физическое порядке, а затем делает сортировку.
Cheers
-
- Уже с Приветом
- Posts: 1099
- Joined: 30 Sep 1999 09:01
- Location: Bryansk,RUSSIA >> Dublin, Ireland
-
- Уже с Приветом
- Posts: 5347
- Joined: 03 Feb 1999 10:01
- Location: NJ, USA
-
- Уже с Приветом
- Posts: 664
- Joined: 05 Jun 2002 01:11
Hello Kemosabe. How's that tundra beastie shaping up ?
Some Microsoft resident Oracle guru must have misled you.
Consider this:
Best regards.
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.
-
- Уже с Приветом
- Posts: 4468
- Joined: 21 Sep 2000 09:01
- Location: Sammamish, WA
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
-
- Уже с Приветом
- Posts: 4468
- Joined: 21 Sep 2000 09:01
- Location: Sammamish, WA
YellowMan wrote:Tengiz, Вы так сказали будто бы этих заметных отличий мало и ширина таблицы одна из самых важных
Дело не в ширине страницы - дело в том, чтобы всю строку уложить в страницу, чтобы для чтения целой строки не приходилось прыгать по цепочке страниц, составляющих одну строку - простые реализации таких цепочек не позволяют делать предварительную выборку. Вплоть до SQL Server 2000 ограничение на размер строки не особенно тревожило подавляющее большинство пользователей. Как только начнёт всерьёз тревожить - вот тогда посмотрим.
Cheers
-
- Уже с Приветом
- Posts: 664
- Joined: 05 Jun 2002 01:11
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
-
- Уже с Приветом
- Posts: 4468
- Joined: 21 Sep 2000 09:01
- Location: Sammamish, WA
vc,
What you say is sure related yet hardly relevant - разумеется оптимизатор Oracle в состоянии сделать план, который будет использовать индекс для сканирования относительно короткого диапазона ключей . Но я говорю о дргугом. Каждый логический оператор помещаемый в план оптимизатором имеет одну или более одной физическую реализацию и решение о том, какую конкретно использовать иногда делается уже на этапе выполнения (а не оптимизации). Физическая реализация оператора сканирования индекса в Oracle не имеет опции оптимизации предварительной выборки страниц индекса, тогда как SQL Server имеет - чему очень способствует ограничение на максимальный размер строки. Это всё, что я имел в виду.
What you say is sure related yet hardly relevant - разумеется оптимизатор Oracle в состоянии сделать план, который будет использовать индекс для сканирования относительно короткого диапазона ключей . Но я говорю о дргугом. Каждый логический оператор помещаемый в план оптимизатором имеет одну или более одной физическую реализацию и решение о том, какую конкретно использовать иногда делается уже на этапе выполнения (а не оптимизации). Физическая реализация оператора сканирования индекса в Oracle не имеет опции оптимизации предварительной выборки страниц индекса, тогда как SQL Server имеет - чему очень способствует ограничение на максимальный размер строки. Это всё, что я имел в виду.
Cheers
-
- Уже с Приветом
- Posts: 664
- Joined: 05 Jun 2002 01:11
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris