MySQL 8.0 – CHAR vs VARCHAR Performance

MySQLmysql-8.0performancequery-performancevarchar

In 2018, does it still hold true that MySQL (InnoDB) CHAR performs better VARCHAR speed-wise?

I've only found a performance comparison explanation that is 7 year old. I've checked the official MySQL 8 CHAR vs VARCHAR but the article speaks about storage only, not about performance. I've also read a notice that VARCHAR causes some problems with table fragmentation (see the very 1st comment to this answer.

Best Answer

I seriously doubt that it ever held true for InnoDB. Even for MyISAM (which really can have FIXED length rows) it was rarely true.

Roughly speaking, this is the order (most overhead first)

  1. Disk hit(s).
  2. Locate the record(s).
  3. Parse the record (split it into columns).
  4. Apply functions and evaluate expressions.

If the data is bigger (as in CHAR being padded), the #1 is impacted. The rest pales into insignificance.

Note: There are 4 flavors of InnoDB ROW_FORMAT.

  • For REDUNDANT, a CHAR(100) CHARACTER SET utf8mb4 always takes 400 bytes.
  • For COMPACT or DYNAMIC, it takes between 100 and 400 bytes.
  • For COMPRESSED, the padding spaces are highly compressible, but still take some space.

Allegedly, the "fixed" size of a CHAR (which, is not all that fixed), tends to prevent block splits. But I kinda doubt it.

My Rule of Thumb: CHAR should almost always be restricted to truly fixed length strings, and most of them are hex or ascii:

country_code CHAR(2) CHARACTER SET ascii
british_postal_code CHAR(6) CHARACTER SET ascii
zip5 CHAR(5) CHARACTER SET ascii
md5 CHAR(32) CHARACTER SET ascii  -- UNHEX() into BINARY(16) is tighter
base64 CHAR(?) CHARACTER SET ascii COLLATION ascii_bin  -- need case-significance

Note: latin1 works equally well as ascii, the 8.0 default of utf8mb4 does not.

(See also my answer to the first link. It starts "Most of the answers in this thread are 5 years old, written before InnoDB and utf8 were defaults. So, let me start over..")