Here are some gotchas
Memory Usage
MyISAM
InnoDB
- caches data pages and index pages.
- one buffer pool and one size before MySQL 5.5
- 1 or more buffer pools starting with MySQL 5.5
Here are some queries I wrote and posted earlier on how to choose a proper size for the MyISAM Key Cache and InnoDB Buffer Pool.
FULLTEXT Indexes
MyISAM
- Supports FULLTEXT indexes
InnoDB
- Starting with MySQL 5.6, yes, but still in beta (UPDATE: MySQL 5.6 exists and has FULLTEXT indexes. If you are using FULLTEXT indexing in MySQL 5.6, make sure you are using the InnoDB-specific FULLTEXT options)
- Before MySQL 5.6, This means you cannot convert MyISAM to InnoDB.
MySQL 5.5 and back
To locate which MyISAM tables have a FULLTEXT index run this query:
select tbl.table_schema,tbl.table_name from
(
select table_schema,table_name
from information_schema.tables
where engine='MyISAM'
and table_schema NOT IN ('information_schema','mysql')
) tbl
INNER JOIN
(
select table_schema,table_name
from information_schema.statistics
where index_type='FULLTEXT'
) ndx
USING (table_schema,table_name);
Whatever comes out of this query cannot be converted to InnoDB until you upgrade to MySQL 5.6.
OPTIMIZE TABLE
MyISAM
- The MyISAM table is shrunk
- ANALYZE TABLE runs index statistics on all indexes
InnoDB
Symlinking InnoDB is definitely not a good idea for regular maintenance of InnoDB.
I wrote posts on why not to do this:
However, if this strictly for the purpose of shrinking a large table, I guess you can symlink the whole data directory where the temp table is to go, but you will have to personally script the shrinkage.
For example
- Suppose the table to shrink is
mydata.mytable
datsdir
is /var/lib/mysql
Your procedure would be
STEP 01: You should create a database called mydatatemp
. Do not put any data in it just yet.
STEP 02: Move the /var/lib/mysql/mydatatemp
over to another disk.
STEP 03: Create a Symlink /var/lib/mysql/mydatatemp
over to the folder on the other disk
STEP 04: chown -R mysql:mysql
against the external folder and against the symlink.
STEP 05: Now perform the data shrinkage as follows:
CREATE TABLE mydatatemp.mytable LIKE mydata.mytable;
INSERT INTO mydatatemp.mytable SELECT * FROM mydata.mytable;
DROP TABLE mydata.mytable;
ALTER TABLE mydatatemp.mytable RENAME mydata.mytable;
To recap, do the following (assuming /tmpdata
is the external disk)
STEPS 01-04
chown mysql:mysql /tmpdata
ln -s /tmpdata /var/lib/mysql/mydatatemp
chown -R mysql:mysql /var/lib/mysql/mydatatemp
then run STEP 05
CAVEAT
This would be rather high risk, but it should work. Please test this with an empty table first like this:
USE mydatatemp
CREATE TABLE mrnorm (id int not null, name varchar(20) primary key (id));
INSERT INTO mrnorm (name) VALUES ('one'),('two'),('three');
SELECT * FROM mrnorm;
If these SQL command worked, go to OS and do this:
cd /tmpdata
ls -l
You should see two files:
Also, test if mrnorm can be moved
CREATE DATABASE helloworld;
ALTER TABLE mydatatemp.mrnorm RENAME helloworld.mrnorm;
Go to the OS and run
cd /tmpdata
ls -l
The table should be gone. Now, do this:
cd /var/lib/mysql/helloworld
ls -l
The table should be there
END OF TEST
Keep in mind that the rename of the table would essentially be controlled copy of the table from one disk to another disk with a proper adjusting of the data dictionary section of the system tablespace in ibdata1. This could take some time.
Best Answer
Decided this was easy enough to investigate myself, even though I still do not understand the underlying specifics of why (feel free to elaborate?)
The answer is: YES int most definitely creates smaller indexes than BIGINT
I made two tables, first with four unsigned INT columns, second with four unsigned BIGINT
I made a compound index across all four columns for each table.
Then I added a million rows of random unsigned smallints 0-65535 to each table.
(each table has identical data, both numbers and row order)
Then I optimized and flushed both tables just to be certain.
INT
BIGINT
added:
I was concerned the random data repeated (I found some cases).
So I added a primary column with auto-increment to each table and emptied them. Then I filled each with the numbers from 1 to 1,000,000 in each column, incrementing for each row sequentially.
INT
BIGINT
So not quite 50% savings but definitely adds up, even for index storage.