I just converted a MyISAM table to InnoDB with around 1.4 million rows. When I converted it to InnoDB, it now shows -1.4 million rows. The table still works as expected, but why does it shows negative in the rows column?
MySQL InnoDB table shows a negative number of rows in phpMyAdmin
innodbmyisamMySQL
Related Solutions
The following exerpt came out of the book "High Performance MySQL, Second Edition".
This is an excellent book and I would recommend it to anyone.
The short answer is:
With your table size and conditions, no matter what method you choose, I think you're potentially in for a long wait.
Table Conversions
There are several ways to convert a table from one storage engine to another, each with advantages and disadvantages.
ALTER TABLE
mysql> ALTER TABLE mytable ENGINE = Falcon;
This syntax works for all storage engines, but there’s a catch: it can take a lot of time. MySQL will perform a row-by-row copy of your old table into a new table. During that time, you’ll probably be using all of the server’s disk I/O capacity, and the original table will be read-locked while the conversion runs.
Dump and import
To gain more control over the conversion process, you might choose to first dump the table to a text file using the mysqldump utility. Once you’ve dumped the table, you can simply edit the dump file to adjust the CREATE TABLE statement it contains. Be sure to change the table name as well as its type, because you can’t have two tables with the same name in the same database even if they are of different types—and mysqldump defaults to writing a DROP TABLE command before the CREATE TABLE, so you might lose your data if you are not careful!
CREATE and SELECT
The third conversion technique is a compromise between the first mechanism’s speed and the safety of the second. Rather than dumping the entire table or converting it all at once, create the new table and use MySQL’s INSERT ... SELECT syntax to populate it, as follows:
mysql> CREATE TABLE innodb_table LIKE myisam_table;
mysql> ALTER TABLE innodb_table ENGINE=InnoDB;
mysql> INSERT INTO innodb_table SELECT * FROM myisam_table;
That works well if you don’t have much data, but if you do, it’s often more efficient to populate the table incrementally, committing the transaction between each chunk so the undo logs don’t grow huge. Assuming that id is the primary key, run this query repeatedly (using larger values of x and y each time) until you’ve copied all the data to the new table:
mysql> START TRANSACTION;
mysql> INSERT INTO innodb_table SELECT * FROM myisam_table
-> WHERE id BETWEEN x AND y;
mysql> COMMIT;
After doing so, you’ll be left with the original table, which you can drop when you’re done with it, and the new table, which is now fully populated. Be careful to lock the original table if needed to prevent getting an inconsistent copy of the data!
I would not worry about application performance with 1 billion rows on a machine that can keep the indexes in memory. If you are serious about reaching 1 billion rows, you first have to do some math:
- What is your record size, and multiply it by 1 billion?
- Next, you need to compute the size of the indexes (more than one index, I'm guessing), and add that on.
- Do you have transactional requirements that you want to have row-level locking for?
- Is this an append-heavy table, or a read heavy table?
Next, move into your application uptime requirements.
- How are you going to back up 1B rows?
- How are you going to deal with a corrupt 1B row table?
- How often will you need to run an OPTIMIZE TABLE?
- How are you going to deal with doing a schema change against a 1B row table? (Adding an index on a 35 million row table on a 2gh dual core box with 2gb ram took me 45 minutes recently.)
I would worry more about the data lifecycle and data management of a multi-gigabyte table file of that magnitude before worrying about performance. With replication, you can make up a lot of the performance. Keeping the data sane and restoring from even small disasters (like corruption induced from bad ram) is more likely going to trouble you first.
I would also encourage you to take the table you have -- and add 1B rows of test data to it. This is extremely insightful to watch what happens to your system. Run some EXPLAINs on your queries against this new huge dataset. Time how long it takes to backup, and restore. You might need to adjust some requirements.
This is an interesting article about 1 billion rows in mysql.
Best Answer
If you look closely, you'll notice it's not a negative sign, it's a tilde, which means "approximately".
InnoDB tables do not store the exact count of rows in the table, so you are being shown approximately how many rows are in the table.
If you use the COUNT(*) function you can retrieve the exact number of rows.