I saw so many questions and answers on this topic MyISAM vs InnoDB on stackoverflow itself.
But, all of the questions and answers are too old and not related to the current stable version of MySQL 5.7.x
By the time so much development must have been done in both MyISAM and InnoDB.
So, I need those differences available presently with version 5.7.x
So, please don't mark my question duplicate and someone please explain the differences these storage engines have currently as well as the differences they have since past.
Also, please explain at what situation which storage engine should be chosen for a table.
Can different tables belonging to the same schema have different storage engines i.e. few tables will have InnoDB and few ones will have MyISAM.
If yes, then how the JOIN queries would get execute between tables with MyISAM and InnoDB?
Is it true that MySQL is going to remove MyISAM storage engine from the future version?
Your assumption that MyISAM has been receiving new development is not correct. MyISAM is not receiving any significant new development. MySQL is clearly moving in the direction of phasing out MyISAM, and using MyISAM is discouraged.
Oracle Corp. has not announced any specific date or version by which they will remove MyISAM. My guess is that MyISAM will never be fully removed, because there are too many sites that wouldn't be able to upgrade, without doing expensive testing to make sure their specific app won't experience any regression issues by converting to InnoDB.
But you might notice that in the MySQL 5.7 manual, the section on MyISAM has been demoted to Alternative Storage Engines, which should be a clue that it's receiving less priority.
In MySQL 5.7, MyISAM is still used for some of the system tables, like mysql.user, mysql.db, etc. But new system tables introduced in 5.6 and 5.7 are InnoDB. All system tables are InnoDB in MySQL 8.0.
MyISAM still does not support any of the properties of ACID. There are no transactions, no consistency features, and no durable writes. See my answer to MyISAM versus InnoDB.
MyISAM still does not support foreign keys, for what it's worth. But I seldom see real production sites using foreign keys even with InnoDB.
MyISAM supports only table-level locking (except for some INSERT appending to the end of a table, as noted in the manual).
MySQL 5.7 supports both fulltext indexes and spatial indexes in both MyISAM and InnoDB. These features are not reasons to continue using MyISAM as they once were.
Both logical backup tools like mysqldump and physical backup tools like Percona XtraBackup can't back up MyISAM tables without acquiring a global lock.
You asked if you could create a variety of tables with different storage engines in the same schema. Yes, you can, and this is the same as it has been for many versions of MySQL.
You asked if you can join tables of different storage engines (by the way, tables don't need to be in the same schema to be joined). Yes, you can join such tables, MySQL takes care of all the details. This is the same as it has been for many versions of MySQL.
But some weird cases can come up when you do this, like what if you update a MyISAM table and an InnoDB table in a transaction, and then roll back? The changes in the InnoDB table are rolled back, but the changes in the MyISAM table are not rolled back, so your data integrity can be broken if you aren't careful. This is also the same as it has been for many versions of MySQL.
Cases where MyISAM has an advantage over InnoDB is a short list, and it's getting shorter.
Some table-scan queries and bulk inserts are faster in MyISAM. InnoDB is better at indexed searches.
MyISAM may use less storage space than the equivalent data stored in an uncompressed InnoDB table. You can further compact MyISAM tables with myisampack, but this makes the MyISAM table read-only.
There are other options these days for compact storage of data in transactional storage engines, for example InnoDB table compression, or MyRocks.
SELECT COUNT(*) FROM MyTable queries (with no WHERE clause) are very fast in MyISAM, because the accurate count of rows is persisted in the MyISAM metadata. InnoDB (or other MVCC implementations) doesn't keep this count persisted, because every transaction viewing the table might "see" a different row count. Only a storage engine that has table-level locking and no transaction isolation like MyISAM, can optimize this case.
Auto-increment that numbers independently for each distinct value in another key column. Again, this requires table-level locking, so it's not supported in InnoDB.
CREATE TABLE MyTable (
group_id INT NOT NULL,
seq_id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (group_id, seq_id)
) ENGINE=MyISAM;
It's still easy to move a MyISAM table from server to server, because the .MYD and .MYI files are self-contained. You can kind of do something similar with InnoDB tables, but you have to use the intricate feature of transportable tablespaces. But this easy-to-move-tables quality of MyISAM no longer works in MySQL 8.0, because of their new data dictionary feature.
Under certain load, MyISAM might be a better choice for internal_tmp_disk_storage_engine, which defaults to InnoDB in MySQL 5.7. If you run lots of queries that create temp tables on disk (in-memory temp tables won't benefit), it can put a strain on the InnoDB engine. But you'd have to have a high query rate for this to matter, and if your queries create so many temp tables on disk, you should try to optimize the queries differently.
MyISAM allows you to set multiple key caches, and define caches for specific tables. But the MyISAM key caches are only for index structures, not for data.
References:
https://www.percona.com/blog/2016/10/11/mysql-8-0-end-myisam/
https://www.percona.com/blog/2017/12/04/internal-temporary-tables-mysql-5-7/
http://jfg-mysql.blogspot.com/2017/08/why-we-still-need-myisam.html
I had this question for a job quiz and got it right: (referring the new version):
MyISAM and InnoDB are two different storage engins that handle CRUD operations differently.
Locking: When approching a row inside a MyISAM storage engin, all the table will be locked by other sessions until the change is commited, unlike InnoDB, which locks only the specific selected row(/s). The lock is released until the session is commited. Locking a table or a row causes suspention by other sessions that try to interact with the same table or row to prevent wrong data manipulations in the table for example.
Transactions: InnoDB supports transactions, unlike MyISAM. Transactions are a colection of 2 or more commands like SELECT, INSERT, UPDATE and DELETE, to a single operation until complishion.
Atomic Operations: When setting a transaction in an InnoDB and
the operation is incompleted - it terminates all the changes and
restore the DB as it was (all or nothin'), so for example, if in the
middle of a transaction there is a syntax error in the code /
datatype mismatch or anything that might interupt the bundle of
commands to finish its operation - all the changes wont be applied,
thanks transactions atomicy. On the other hand, when using an
MyISAM storage engin, if a bundle of commands "breaks" (for any
reason), the operation stops immediately and all the
tables/rows/data that were affected will remain affected, which
might cause a corrupt data in the database (...and a headache).
B. Running an operation on MyISAM are set on the spot,
whereas InnoDB allows you to use the "ROLLBACK"s to discard any
change, which comes best in handy when running transactions.
Transaction Logs: When creating a transaction without a
transaction log in between, you can apply any changes on the table/s
in the DB, and if the table have a clustered index (for example),
the data will have to search where exactly it has to be inserted and
only then apply the change. In a case where there is a transaction
log in between the DB and the transaction, the changes will be sent
to the transaction log first and will set its order in the table
before sending the change to the DB - which will be less time
consuming. The DB saves logs from all the transactions that were
made, which can help to choose to restore any transaction previously
made, and recover all changes. When set to a "simple" recovery model- transactions are deleted from the transactions log and wont be able to recover data (used usually on DEV environments). When set to
"full" recovery model, all transactions are saved and listed, ready
to be restored - this is used usually on production environments
which might cause problems like preformance issues - so backing them
up and deleting from the server could be a solution. When set to a
"bulk-logged" recovery model saved transaction logs only for
specific "important" changes and commands (import,export,
insert-select, select-into, reorganaizing/rebuilding indexes), and
might prevent preformance issues.
Foreign keys: MyISAM dosn't use foreign keys, unlike InnoDB. When a table column has a foregin key set to point on an other table column, when any update/delete occures on the pointed table, it will know that the changes have to be applied on the other table pointing at it. This create a some kind of a link between the two table and keep data in sync. Setting tables with FKs might require more effort which might be considered as a disadvantage (?).
FULLTEXT indexing: InnoDB doesn't support FULLTEXT indexing in its previous versions - MyISAM does support it. Switching to MyISAM wont be the best solution so just update MySQL to a verion which does support FULLTEXT indexing.
FULLTEXT indexing can take texts like titles, comments, ect' - and search it (this should be a better option than the "LIKE" command in this case).
Spatial data types: Supported only on InnoDB.
To sum all up, InnoDB will be usually more reliable in terms of data handling, validity & recovery. For newer versions InnoDB will support FULLTEXT indexing for mainly searches - when using older versions with no option to update MySQL, using MyISAM will be great.
Well, I know already that:
1. InnoDB is faster for data insertion but slower on data retrieval.
2. MyISAM is faster for data retrieval but slower for data insertion.
My situation is a bit different, and I just cant figure out what settings are good for me, let me explain:
My software inserts each user's hit's data (IP, Host, Referral data etc) to a Logs table at run-time. Previously, I used to write this data to a .csv file and then import it to the DB after predefined minutes/hours, but it was not good for me, I need real-time data.
I have several auto processes that run each minute, getting data from the Logs table, hence I need this to be fast.
My question is, what type of MySQL engine should I use for the Logs table, InnoDB or MyISAM?
currently, I'm using InnoDB cause it's faster for insertion, however, should I leave it this way, or switch back to MyISAM?
Thanks
InnoDB is faster for data insertion but slower on data retrieval. 2. MyISAM is faster for data retrieval but slower for data insertion.
Not true. In fact, under most workloads it's just the opposite.
That prevailing wisdom you cite is based on InnoDB of about 2004.
My question is, what type of MySQL engine should I use for the Logs table, InnoDB or MyISAM?
If you care about your data not getting corrupted, use InnoDB.
I'm trying to create a Wikipedia DB copy (Around 50GB), but having problems with the largest SQL files.
I've split the files of size in GB using linux split utility into chunks of 300 MB. e.g.
split -d -l 50 ../enwiki-20070908-page page.input.
On average 300MB files take 3 hours at my server. I've ubuntu 12.04 server OS and Mysql 5.5 Server.
I'm trying like following:
mysql -u username -ppassword database < category.sql
Note: these files consist of Insert statements and these are not CSV files.
Wikipedia offers database dumps for download, so everybody can create a copy of Wikipedia.
You can find example files here: Wikipedia Dumps
I think the import is slow because of the settings for my MySQL Server, but I don't know what I should change. I'm using the standard Ubuntu MySQL config on a machine with a decent processor and 2GB RAM. Could someone help me out with a suitable configuration for my system?
I've tried to set innodb_buffer_pool_size to 1GB but no vains.
Since you have less than 50GB of memory (so you can't buffer the entire database in memory), the bottleneck is the write speed of your disk subsystem.
Tricks to speed up imports:
MyISAM is not transactional, so much faster in single threaded inserts. Try to load into MyISAM, then ALTER the table to INNODB
Use ALTER TABLE .. DISABLE KEYS to avoid index updates line by line (MyISAM only)
Set bulk_insert_buffer_size above your insert size (MyISAM only)
Set unique_checks = 0 so that unique constrains are not checked.
For more, see Bulk Data Loading for InnoDB Tables in MySQL Manual.
Note: If the original table have foreign key constraints, using MyISAM as an intermediate format is a bad idea.
Use MyISAM, usually much faster than InnoDB, if your data base isnt transaction oriented. Did you research into using any table partitioning/sharding techniques?
Converting huge MyISAM into InnoDB will again run into performance issues, so I am not sure I would do that. But disabling and re-enabling keys could be of help...
Environment: JSF2, persistence with Hibernate, MySQL
I have a database that is rappidly filling because of a table with image data. That data is never searched but only directly accessed by id. Problem is that it stays in the database and so enlarges the backups and the runtime memory usage of the database.
I'm thinking that there could possibly be multiple solutions:
Tell MySQL that the table should not be cached and/or kept in memory.
Don't use MySQL at all for that table. Just let persistence know that this should be stored on disk directly.
???
But I haven't found a way to do either. Please advice.
Thanks,
Milo van der Zee
Storage type depends on storage engine in MySQL. Only tables having MEMORY storage engine are stored in RAM others are stored on disk.
In select queries you can use SELECT SQL_NO_CACHE to tell MySQL not to cache query data in MySQL query cache.
You can partition the table by defining partitions on table. This will make inserts and selects faster.
You can also create day wise tables like table_name_2012_07_20 and archive tables with old dates and to store data in compress format you can either use Archive storage engine or if you are using MyIsam storage engine then do myisamchk or myisampack to save disk space on the hard drive.
I've a database with 3 of the tables having rows in excess of 20 million each. I've used GUIDs as primary keys (unfortunately). Now our database is about 20GB and growing 5GB per month.
It takes about 2 hrs to take full backup of the database, and 30hrs to restore on a box with 4GB RAM.
We once have all the tables from database disappeared. other mysql databases in same server were alright except one - for which only data was disappeared leaving empty tables.
A select query (among many slow queries) - which get max of a date column in one of 20m table takes about 5 mins to return result. This query used pretty frequently.
What I'm looking answers for
recommended db design changes
ways to improved select query performance - max date column on 20m records
other queries' performance
how to go about handling future db growth
Thanks all for your attention.
I've seen setups of larger size (with InnoDB as storage engine and a GUID as a primary key), and there were no such problems.
We once have all the tables from database disappeared. other mysql databases in same server were alright except one - for which only data was disappeared leaving empty tables.
The tables may seem empty if the system LSN has gone below the each page's LSN. This may happen if the InnoDB logfiles are corrupt. InnoDB, however, will issue a warning in this case.
A select query (among many slow queries) - which get max of a date column in one of 20m table takes about 5 mins to return result. This query used pretty frequently.
Create an index on this column, the query will be instant.
Please post the exact query and I'll tell you how to create the best index.
I see no problem in the DB design as such, most probably it's something with your server.
Is it possible to reproduce this behavior on another server with a clean vanilla MySQL installation?
You may also want to try to split data between the tables. Set innodb_file_per_table and restore from the backup.
A free alternaive to innodb hot backup is Percona XtraBackup Tool.
For backup, you could use the innodb hot backup tool. This not only lets you do consistent backups while your database is up, but the restore is much faster than the one you're doing (I'm assuming mysqldump?). It does cost money.
You might also try Mydumper: http://www.mydumper.org/
It is a great tool and is free and open source