Sql Server Row Size Limit
Once again I've run into a limitation of SQL Server that really threw me off. SQL Server's Row Byte size is limited somewhere right around 8k bytes for physical data stored in the database. This means if you have a few large varchar or nvarchar fields it's actually quite easy to outrun the size of a row. This doesn't apply to Text or Image fields which are stored separately, but it's still very frustrating.
Especially since I recently decided to ditch Text fields in favor of rather larger varchar fields because they are easier to manage for searching and generally perform better. Unfortunately I found out just today that it's quite likely that I'll overrun the row limit on several occasions. It seems ironic that a varchar field can be 8000 bytes long which would eat up just about all of the full row size in one chunk...
So, anybody have good guidelines on when to use Text fields vs. varchars? I came to the decision to change my text fields after reading up on varchars more closely and just liking the idea of not having to do crazy, unoptimized conversion gyrations to run queries into against the Text fields originally.
This is yet another instance where I'm surprised by some of the inflexibility that a SQL Backend provides. This limit seems pretty superficial based on some engine behavior that probably dates back to the Sybase days...
Live an learn. I'm off reconfiguring the Database one more time...
The Voices of Reason
# re: Sql Server Row Size Limit
I know this isn't the best news, but I think SQL Yukon addresses some of these issues.
1. There is a Varchar(max) which I'm not sure how it technically works, but is supposed to be stored inline like varchar() without affecting the record length, or perhaps using whatever is available for the record. I'll have to read read up on it.
2. Yukon will have an XML data type, which allows for storing blob, and you can use the new xquery stuff on it. Not sure if you can pull text out of a specific attribute.
3. Full text search is actually supposed to work in Yukon.
Well, I know this doesn't solve your immediate problem. But, one solution with 2000 is to have a seperate table which you can join to the main table. The secondary table can have varchar(8000) in it so you don't have to worry that it wil make the record excede the record size limit.
# re: Sql Server Row Size Limit
# re: Sql Server Row Size Limit
# re: Sql Server Row Size Limit
Am I wrong ?
Wouldnt be the first time :)
# re: Sql Server Row Size Limit
# re: Sql Server Row Size Limit
# re: Sql Server Row Size Limit
# re: Sql Server Row Size Limit
# re: Sql Server Row Size Limit
# re: Sql Server table limit
i need the exact size of one table in sqlserver
if anyone known plz send me imd
# re: Sql Server Row Size Limit
Not sure what the limit is.
Running the same insert query for SQL Server 2000 resulted in the message below. This should be a good improvment in the 2005 version.
Cannot create a row of size 43725 which is greater than the allowable maximum of 8060.
The statement has been terminated.
# re: Sql Server Row Size Limit
# re: Sql Server Row Size Limit
# re: Sql Server Row Size Limit
I want to know "is there a difference in performance between varchar(100) and varchar (500)"
(Assume actual data is always less than 100 )
Why do we have to specify size of the varchar?.
Sql server is going to store only the actual length of the data, so from table size point of view , I/O point of view, size of the varchar should not matter ( as long as total row size is less than 8K)
# is there a difference in performance between varchar(100) and varchar (500)"
I want to know "is there a difference in performance between varchar(100) and varchar (500)"
(Assume actual data is always less than 100 )
Why do we have to specify size of the varchar?.
Sql server is going to store only the actual length of the data, so from table size point of view , I/O point of view, size of the varchar should not matter ( as long as total row size is less than 8K)
# re: Sql Server Row Size Limit
# Why I can not insert more than 1500 charactor into SQL server 2000?
Thanks
# re: Sql Server Row Size Limit
In the beginning, I did the multi-varchar field hack like the one suggested early in this thread. But it's cumbersome and frequently buggy. I tried the convoluted ways of dealing stepping through text/blob types, and that wen't nowhere.
The whole time, there was this Microsoft Full-Text-Search thing sitting the background, I never really knew what it did. On the latest project I finally sat down and play with it and it turned out to be and answer to all the problems I've ever had with this issue.
It is fairly easy to set, it is blazingly fast in all of out applications, and it's more accurate than using the LIKE operator.
In our application, we don't actually index the TEXT fields of our data, we have a secondary joined table that holds TEXT fields that are initially copied in from the master table, but then manipulated specifically for the FTS engine. For example, we have data being combined into a single searchable table comeing from a multitude of sources. It was going to be very difficult to cross-tab all the different sources and add a data point like "this item is hot". Because the table structure was being determined by an external source. So we simply added a special string to the FTS TEXT field like "HOTTOHHOT" and now when we want to get the hot items, we do a FTS query and it comes back almost as fast as our queries that rely on integer lookups.
I highly recommend looking at FTS to solve some of the issues stated above.
# re: Sql Server Row Size Limit
Remember that TEXT and BLOB fields are really just a pointer to a linked list of 2K pages sitting somewhere else. So in a table that contains multiple varchar(2000) field, the PK sectors will always be 8K apart on the disk (because varchar fields are stored inline in the record). So the heads on the disk need to jump around more.
Conversely, a table with just a PKID and a couple of TEXT fields will be much tighter, because the pointer only takes up (I forget the exact size, but it's tiny).
So in the table with large varchar fields, the space is allocated in every record, even when there is nothing in the varchar field. So that table with 100 "emptry" records will take up 800K on disk (8 x 100k)
Whereas that same table using TEXT fields will only take up the size of the PK + the size of the pointer, since an empty TEXT datatype takes up no space.
I don't know if I got all that right, but once I internalized the basic idea, it really helped me design tables better. Sometimes you want a contiguous space for you data, always allocated and searchable with LIKE. Other times, you just want to store a lot of data infrequently, then the TEXT mechanism is vastly superior to the varchar(really high number) mechanism.
Unfortunately, it looks like they are dropping the TEXT datatype in future versions of SQL server.
# re: Sql Server Row Size Limit
# re: Sql Server Row Size Limit
For all you guys looking to find available bytes in a table row for SQL Server 2005 (haven't tested it against previous version but should work) here is a scalar function that accepts a table name and returns the remaining bytes left for expansion
Hope it helps !!
-- ================================================
-- Template generated from Template Explorer using:
-- Create Scalar Function (New Menu).SQL
--
-- Use the Specify Values for Template Parameters
-- command (Ctrl-Shift-M) to fill in the parameter
-- values below.
--
-- This block of comments will not be included in
-- the definition of the function.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Ruchir T
-- Create date: 01/02/2008
-- Description: returns the number of bytes left to use for creating new columns
-- =============================================
CREATE FUNCTION available_tablerowsize
(
-- Add the parameters for the function here
@tablename char(50)
)
RETURNS int
AS
BEGIN
-- variables to track fixed and variable column sizes
DECLARE @num_columns int
DECLARE @result int
DECLARE @num_fixed_columns int
DECLARE @fixed_data_size int
DECLARE @var_data_size int
DECLARE @num_var_columns int
DECLARE @max_var_size int
DECLARE @null_bitmap_size int
DECLARE @row_size int
-- Find the total number of columns
select @num_columns = count(*)
from syscolumns,systypes
where syscolumns.id=object_id(@tablename)
and syscolumns.xtype=systypes.xtype
-- Find the size occupied by fixed length columns (Note: not possible to exist outside the 8060 bytes limit)
select @num_fixed_columns = count(*)
from syscolumns,systypes
where syscolumns.id=object_id(@tablename)
and syscolumns.xtype=systypes.xtype and systypes.variable=0
select @fixed_data_size = sum(syscolumns.length)
from syscolumns,systypes
where syscolumns.id=object_id(@tablename)
and syscolumns.xtype=systypes.xtype and systypes.variable=0
-- Find the size occupied by variable length columns within the 8060 page size limit
-- number of variable length columns
select @num_var_columns=count(*)
from syscolumns, systypes
where syscolumns.id=object_id(@tablename)
and syscolumns.xtype=systypes.xtype and systypes.variable=1
-- max size of all variable length columns
select @max_var_size =max(syscolumns.length)
from syscolumns,systypes
where syscolumns.id=object_id(@tablename)
and syscolumns.xtype=systypes.xtype and systypes.variable=1
-- calculate variable length storage
begin
if @num_var_columns>0
set @var_data_size=2+(@num_var_columns*2)+@max_var_size
--set @var_data_size = @num_var_columns*24
else
set @var_data_size=0
end
-- If there are fixed-length columns in the table, a portion of the row, known as the null bitmap, is reserved to manage column nullability.
select @null_bitmap_size = 2 + ((@num_columns+7)/8)
-- Calculate total rowsize
select @row_size = @fixed_data_size + @var_data_size + @null_bitmap_size + 4
-- Return the available bytes in the row available for expansion
select @result = 8060 - @row_size
RETURN @result
END
GO
# re: Sql Server Row Size Limit
It would be nice to "truncate" microsoft from our lives forever, but I am not quite sure how!
# re: Sql Server Row Size Limit
# re: Sql Server Row Size Limit
Microsoft plans to phase out TEXT and NTEXT in favor of these new alternatives mainly because they perform better. One reason TEXT performs badly is that the contents are stored in other pages than the rows that include them, necessitating extra reads. A VARCHAR(MAX) may be wholly stored on the page, just like a VARCHAR(N). If it is too long to fit on the row page, part or all of it may be stored off-page, like with TEXT. It is significantly more complicated to implement this, but the performance gains can be huge. For example, if you have a "WHERE Contents LIKE 'abc%' and at least the first 3 bytes of text in the Contents column are on the row page, the filtering will be very fast, versus loading a separate extra page for each row you are filtering.
# re: Sql Server Row Size Limit
Way back (about 6 years ago) we had ditched using Oracle "long" fields (equivalent of "text" in SQL) in favor of concatenated varchar(2000) fields for a particular app we had - in Oracle 7.2 (not sure about current versions) you could only have 1 long per table and it had to be the last column. What a pain! So we created a generic "notes" table that had 20 or so varchar(2000) fields - when we needed a "long" we used a foreign key and type field combination to create records in "notes" that then became related to that record. We then had a generic form "class" that had an editbox - in the "read" we would concatenate all the varchar(2000) fields and rows. In the save we would break it all apart again. It was klunky as hell but it worked great and gave us tons of flexibility in the data model to add "long" types anywhere. Plus, we could change the model much easier going forward without that last column constraint. The tool we were using was Uniface but I imagine this could easily be done with some classes in VFP pretty easily.
Good luck!
- Randy