Is there a performance difference in MySQL between varchar sizes? For example,
varchar(64000). If not, is there a reason not to declare all varchars with the max size just to ensure you don't run out of room?
- Anybody can ask a question
- Anybody can answer
- The best answers are voted up and rise to the top
The answer to this is actually rather complex. The short version: there is a difference.
For (2) I admit the wire protocol is not something I am intimately familiar with, but the general advice here is try and apply at least some minimal effort to guess the length.
A varchar column that size makes queries on the entire table more likely to use temporary tables. According to the High Performance MySQL book. When the optimizer tries to see if it can run this query in memory or if it needs a temp table, it looks at the row size based on the table definition, meaning, for speed it does not try to see how much of the 64K characters you re actually using. This is why the writers recommend you not stretch out that definition way beyond the actual possible values that would go in the column. Obviously, if you set yourself up for more queries going into temp tables (even if the actual data size could fit in RAM) you have now incurred I/O penalties you could have avoided.
You must realize the tradeoffs of using CHAR vs VARCHAR
With CHAR fields, what you allocate is exactly what you get. For example, CHAR(15) allocates and stores 15 bytes, no matter how characters you place in the field. String manipulation is simple and straightforward since the size of the data field is totally predictable.
With VARCHAR fields, you get a completely different story. For example VARCHAR(15) actually allocates dynamically up to 16 bytes, up to 15 for data and, at least, 1 additional byte to store the the length of the data. If you have the string 'hello' to store that will take 6 bytes, not 5. String manipulation must always perform some form of length checking in all cases.
The tradeoff is more evident when you do two things:
Obviously, VARCHAR holds the advantage since variable-length data would produce smaller rows and, thus, smaller physical files.
Since CHAR fields require less string manipulation because of fixed field widths, index lookups against CHAR field are on average 20% faster than that of VARCHAR fields. This is not any conjecture on my part. The book MySQL Database Design and Tuning performed something marvelous on a MyISAM table to prove this. The example in the book did something like the following:
This directive forces are VARCHARs to behave as CHARs. I did this at my previous job back in 2007 and took a 300GB table and sped up index lookups by 20%, without changing anything else. It worked as published. However, it did produce a table almost double in size, but that simply goes back to tradeoff #1.
You could analyze the data being stored to see what MySQL recommends for column definition. Just run the following against any table:
This will traverse the entire table and recommend column definitions for every column based on the data it contains, the minimum field values, maximum field values, and so forth. Sometimes, you just have to use common sense with planning CHAR vs VARCHAR. Here is a good example:
If you are storing IP addresses, the mask for such a column is at most 15 characters (xxx.xxx.xxx.xxx). I would jump right at CHAR(15) in a heartbeat because the lengths of IP addresses will not vary all that much and the added complexity of string manipulation controlled by an additional byte. You could still do a PROCEDURE ANALYSE() against such a column. It may even recommend VARCHAR. My money would still be on CHAR over VARCHAR in this instance.
CHAR vs VARCHAR issues can be resolved only through proper planning. With great power comes great responsibility (cliche but true)
It's my understanding that the smaller fields may be includable in the index directly, whereas the longer ones cannot. Due to that limitation, if you want the strings to be indexable, I would say keep them shorter. Otherwise, no, being as how they're both varchar then ops like sorting or comparing will operate in like time, whether the fields are 25 or MAX.
This phrase implies that you ask the question because you're not sure about the data you'll be storing in the database. If that's true, you'll be well served to find out as soon as you can, because you'll need that for capacity planning. If you might be getting data elements with 7000 characters, for example, you need to know because that would have performance implications on any DBMS.
That said, I prefer to have column sizes related to the expected contents. For example, a phone number is unlikely to be longer than 50 characters, even if you include a country code and extension. Similarly, a zip or postal code will most likely be 20 characters or less.