Matt,
Thanks for the great reply. We have a database that has been migrated
over to MySQL 4.0, and the column-definitions are a bit wacked - way
more space is allocated than is needed for many columns. I think you are
using MyISAM tables; we are using InnoDB. I think it woudl be worth
dropping some indexes after seeing how much free tablespace there is,
and then re-creating those indexes with a length specifier of the column
size, and see if the amount of free tablespace changes. If it doesn't,
then MySQL is indexing the whole column.
The question arose due to a unique index we have on a table; we can't
seem to get the data in from our other database - the index fails, yet
the value that it fails on appears only once in the table we are copying
from. I wondered if maybe MySQL was defaulting the length of the index,
and causing it to conflict with an other value. I don't believe it is,
however, as there is no value that is even remotely similar.
Regardless, I think it might be a worthwhile exercise to take a close
look at our data, and see if we can guesstimate appropriate lengths.
Thanks,
David.
Matt W wrote:
Hi David,
Great questions:
- Original Message -
From: David Griffiths
Sent: Friday, May 28, 2004 6:05 PM
Subject: Specifying an index length and the default value
The length of indexes on varchar and char indexes can be specified at
index creation.
What is the default length of an index if no length is provided?
The default is to index the whole column length (of course that's not
possible with TEXT/BLOB columns).
The High Performance MySQL book hints that the index-length used is
specific for each entry in the indexed column (ie an index on a column
where the average length of the data is 8 bytes would take up (8 x
number-of-rows) bytes).
Well, maybe. It depends... see below.
If a column was a varchar(128), would the index use 128 bytes per entry,
or would it use the number of bytes in each row of the indexed column.
So if each row had exactly four characters, the index would use four
bytes per row, but if a row was added with 8 characters, that one row
would have an index entry that was 8 bytes in size and the rest would
remain at 4?
I don't know that it's in the manual anywhere, but from experimenting and
stuff, I've found that, generally, indexes with a TOTAL length (if there's
multiple columns) of = 8 are fixed-length. That is, they'll always use 8
bytes/row even if a string doesn't take up that much space. Actually, this
up to 8 bytes, fixed length behavior might only occur with indexed
character columns (e.g. 100% numeric indexes may stay fixed-length
regardless of their size). I'm not sure...
You can change the behavior, however, by setting PACK_KEYS in ALTER/CREATE
TABLE. The default, in MySQL 4+, is DEFAULT, where MySQL decides whether
to use fixed-length keys (faster) or packed variable-length keys (space
saving) depending on the index. Setting PACK_KEYS to 0 forces all
fixed-length keys (I *think* 0 in 3.23 is like DEFAULT in 4+). Setting
PACK_KEYS to 1 packs all *non-unique* indexes, even if they're numeric or
= 8 bytes.
It's useful to use myisamchk to find out the properties of columns in an
index:
myisamchk -dv /path/to/db/table
In the second half of the output, you will see information about the
table's indexes. Some things you may see in the Type column are:
packed - I think this is for character indexes that have prefix compression
(multiple index entries that start with the same characters are
compressed). Any unused space at the end of the index (storing 10 chars in
a 32 character index) is also not stored (like you were talking about
above).
prefix - I think this one is for numeric indexes that have prefix
compression (in an INT index, values 0 - 255 use the same 3 bytes, so those
can be compressed).
stripped - This is for character indexes that have unused trailing space
stripped (again, like you were talking about above).
Now, having said that, there's still some things in the myisamchk output
that I can't figure out: like sometimes there will be packed and
stripped on the same column; sometimes not. And other things I can't
remember now that don't seem consistent. I just kinda figured it out on my
own since I don't know that there are official descriptions anywhere.
( But at least it gives you more of an idea of what's going on internally
than you can get from a SQL query. :-)
Thanks for any input.
David.
Hope that helps somewhat.
Matt
--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:http://lists.mysql.com/[EMAIL PROTECTED]