Since UTF-8 uses 3 bytes per characters, you may not have allocated enough for character fields.
By default, an index key for a single-column index can be up to 767
bytes. The same length limit applies to any index key prefix. See
Section 13.1.13, “CREATE INDEX Syntax”. For example, you might hit
this limit with a column prefix index of more than 255 characters on a
TEXT or VARCHAR column, assuming a UTF-8 character set and the maximum
of 3 bytes for each character. When the innodb_large_prefix
configuration option is enabled, this length limit is raised to 3072
bytes, for InnoDB tables that use the DYNAMIC and COMPRESSED row
formats.
When you attempt to specify an index prefix length longer than
allowed, the length is silently reduced to the maximum length. This
configuration option changes the error handling for some combinations
of row format and prefix length longer than the maximum allowed. See
innodb_large_prefix for details.
The InnoDB internal maximum key length is 3500 bytes, but MySQL itself
restricts this to 3072 bytes. This limit applies to the length of the
combined index key in a multi-column index.
The maximum row length, except for variable-length columns (VARBINARY,
VARCHAR, BLOB and TEXT), is slightly less than half of a database
page. That is, the maximum row length is about 8000 bytes. LONGBLOB
and LONGTEXT columns must be less than 4GB, and the total row length,
including BLOB and TEXT columns, must be less than 4GB.
If a row is less than half a page long, all of it is stored locally
within the page. If it exceeds half a page, variable-length columns
are chosen for external off-page storage until the row fits within
half a page, as described in Section 14.3.12.2, “File Space
Management”.
Although InnoDB supports row sizes larger than 65,535 bytes
internally, MySQL itself imposes a row-size limit of 65,535 for the
combined size of all columns:
mysql> CREATE TABLE t (a VARCHAR(8000), b VARCHAR(10000),
-> c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),
-> f VARCHAR(10000), g VARCHAR(10000)) ENGINE=InnoDB; ERROR 1118 (42000): Row size too large. The maximum row size for the used table
type, not counting BLOBs, is 65535. You have to change some columns to
TEXT or BLOBs See Section E.10.4, “Table Column-Count and Row-Size
Limits”.
Best Answer
5.5.14 and 5.6.3 and 5.7 have
innodb_file_format=Barracuda
as an option.Prior to 5.7.7, do these:
In 5.7.7 and after, most of that is defaulted as you need.
DYNAMIC
is the format you need -- it leaves only 22 bytes in the main part of the row (which is limited to about 8KB), and puts the rest in overflow blocks. This applies toVARCHAR
,TEXT
,VARBINARY
andBLOB
. 22*156 is well under 8K. "When the row is too long, InnoDB chooses the longest columns for off-page storage." That is, some of the shorter columns for a given row may still reside 'on-page'.I think the "22" is a 2-byte length, plus a 20-byte "pointer" to the data. That is, none of the data is stored 'on-page', and the 768 is not relevant.
Another possibility (but I don't recommend it) is to increase the default page size from 16KB to 32KB, thereby increasing the max from about 8K to about 16K. (There is a 64KB page size, but the limit is still 16KB for each row.)
Also,
COMPRESSED
can be used instead ofDYNAMIC
, but again, I don't recommend it, especially before 5.7. ("Compressed = Dynamic plus compression.")Splitting the table ("vertical partitioning") is a good idea.
MyISAM is a bad idea.
Checking to see if you really need 1000 is a good idea.