I'm currently doing research on the best ways to provide an advanced search for my php project.
I have narrowed it down to using FULLTEXT search rather than using LIKE to find matching strings in a table row. However, to do this it appears I need to sacrifice using the InnoDB engine which will make me lose the ACIDity of transactions and table relationships.
Is it really worth using the MYISAM mysql engine or are there better ways of providing search functionality.
Any pointers would be appreciated!
It really depends on the application... Using MyISAM for anything that needs referential integrity is an instant fail. At the same time, it's text search isn't all that efficient.
Basically, there are two ways to go. If you find you don't need true referential integrity, consider a NoSQL datastore. MongoDB is a great document store database.
If, on the other hand, you really need referential integrity, but also need fast, indexed full-text searching, you might do better to use Sphinx or Apache Solr to create an indexed cache for full-text search.
Either way, I consider MyISAM to be a legacy datastore. I wouldn't use it on a new project. YMMV.
MyISAM has several drawbacks - lack of transaction support, table-level locks which makes it very slow in heavy read+write load type. Another inconvenience of MyISAM tables - they are not crash safe so you can lost some data in case of unexpected shutdown or power loss on server. However MyISAM is very fast on some queries.
Regarding the FullText search I would suggest to use InnoDB + external search engine like Lucene or Sphinx so you could benefit from both safe and reliable storage engine and fast Full-text queries.
For quick start with InnoDB and Sphinx you can refer to http://astellar.com/2011/12/replacing-mysql-full-text-search-with-sphinx/
MySQL 5.6 supports FULLTEXT indexes with InnoDB (released Feb 2013). See:
http://dev.mysql.com/doc/refman/5.6/en/fulltext-search.html
Related
One of my friends, who is a DBA, commented that mixing MyISAM and InnoDB is fairly common among the DBA community, while designing schema in MySQL.
My question is, if this is true, then how good it is? Does it have any effect in the maintainability, scalability etc?
There are generally very few good reasons remaining to use MyISAM. Newer versions of MySQL (5.5+) have extended InnoDB to support all the features that were previously only available on MyISAM (such as fulltext and geospatial indexing), and InnoDB performance is usually considerably better than MyISAM when configured properly.
Unless you are working with an older version of MySQL, or if you have a very good reason for doing so, I'd recommend just using InnoDB throughout any new database design.
IMHO, this is one of the terrible things about MySQL: that it makes you choose between speed and full-text indices (MyISAM) and referential integrity and transactions (InnoDB). If you can, I highly recommend switching to PostgreSQL: in addition to a number of other advantages, you get speed, full-text indices, transactions, and referential integrity in one storage engine. (I no longer use MySQL for new projects at all.)
If you must stick with MySQL, I recommend using InnoDB on all tables unless you have a particular reason not to.
On a practical note.
I have done it a number of times. Notably on one system where queries were locking a whole table as myisam and we converted a number of the critical tables to innodb so they locked at the row level. This removed some bottlenecks from the process and i was with the company for another 18 months after this change with no problems from that solution. The application being supported made fairly intensive use of the database as well so any inadequacies tended to come to light quite quickly.
For past few days I was in a great confusion deciding whether to use MyIsam or Innodb, with both having their own pros and cons. My table will have large amount of data with heavy INSERT, UPDATE and SELECT operations.
I decided to create two tables of same structure; tbl_mytbl_innodb(innodb engine) and tbl_mytbl_myisam(myisam engine) I then created two triggers on tbl_mytbl_innodb for INSERT and UPDATE events that will insert/update tbl_mytbl_myisam. So it will always write to tbl_mytbl_innodb and read from tbl_mytbl_myisam.
Is this process correct, or do I need to do it a better way?
That's a silly way to go. The only time you should use both in parallel is if you require transactions+foreign keys AND fulltext indexes. You'd use triggers to sync up the fulltextable fields in a MyISAM table, and otherwise keep everything in InnoDB.
There's few usage cases where MyISAM is preferable over InnoDB, and the major one is the lack of fulltext support in InnoDB.
I'd say that's the opposite of a correct process. My personal recommendation is use InnoDB for almost all business activities, as it supports transactions... the only use I've found for MyISAM is full text searches (dunno why that's not available in InnoDB) but I freely admit that's a personal preference.
Using triggers to synchronize the same data across multiple tables can't be good. Define your business requirements and choose an engine. If you need to use the other engine for a specific requirement, define that and populate a subset of data as necessary.
I'm running a django system over mysql in amazon's cloud, and the database default is innodb. But now I want to put a fulltext index on a couple of tables for searching, which evidently requires myisam.
The obvious solution is to just tell mysql to ALTER TABLE to myisam, but are there going to be any issues with that?
One that comes to mind is that I'll have to remember to do that any time I build a new version of the database, which should theoretically be rare, but there doesn't seem to be a way to tell django to please set the storage engine at the table level. I guess I could write a migration (we use south).
Any other things I might be missing? What could possibly go wrong?
Will the application notice? Probably not.
Will it cause problems? Only when things go wrong. MyISAM is not a transactional storage engine. If you change the data in a MyISAM table while inside of a transaction, then have to roll back changes, the changes in that table won't be rolled back. It's been a while since I tried to break it horribly, but I'm willing to wager that MySQL won't even issue a warning when this happens. This will lead to data consistency issues.
You should seriously consider external search software instead of a fulltext index, like ElasticSearch (integrates at the application level), or Sphinx (integrates at the MySQL level, though if you're using RDS instead of MySQL directly, I don't think you'll be able to use it).
the following may be of help:
use a myisam fulltext table to index back into your innodb tables for example:
Build your system using innodb:...
Any way to achieve fulltext-like search on InnoDB
I read the following article yesterday (http://blogs.sitepoint.com/2010/11/19/mysql-mistakes-php-developers/) and it wrote the following:
MySQL has a number of database engines but you’re most likely to encounter MyISAM and InnoDB.
MyISAM is used by default. However, unless you’re creating a very simple or experimental database, it’s almost certainly the wrong choice! MyISAM doesn’t support foreign key constraints or transactions which are essential for data integrity. In addition, the whole table is locked whenever a record is inserted or updated: it causes a detrimental effect on performance as usage grows.
The solution is simple: use InnoDB.
I've always used MyISAM because it was the default. What do you think?
If I were to upgrade to InnoDB, in phpMyAdmin, can I just edit each table and change it to innoDB or is there a more complex process to perform?
Thanks!
Yes, you can swap in and out engines like used underwear, if you like, without much trouble. Just change it in phpmyadmin.
But I wouldn't change it for the sake of changing it. Do you need to use foreign keys? Change it. Do you need row-level-locking instead of table-locking? Change it.
It's worth noting that there are good reasons to use MyISAM, too. Take a look at FULLTEXT indexing. You can't do that with InnoDB.
UPDATE
As of MySQL 5.6 FULLTEXT has been implemented for InnoDB tables as well. Here is the manual.
Sorry for bumping an old question, but this also helped me a lot to choose which engine, especially since MyISAM is faster for reads and my database tables had more read the write:
http://www.rackspace.com/knowledge_center/article/mysql-engines-myisam-vs-innodb
I heard this today during interview for java developer. I had to list some advantages of MyISAM over InnoDB and why it's still being widely used. And they were waiting to hear from me the answer as the title of this question.
As I understand from their own answer: MyISAM doesn't have foreign keys and DB can be easily clustered (one table per server for example). But why can't we simply create InnoDB tables without foreign keys? This explaination sounds strange to me..
There is no silver bullet answer here. You need to know the pros and cons of each before you make a decision on which one you use for any particular application.
InnoDB:
supports FK's
supports transactions
uses a large memory buffer for operation
supports row level locking
But has a much higher maintenance cost -- you really need to tune your memory usage, configure your table files, etc.
MyISAM:
has a bunch of special column features that InnoDB doesn't, like:
full text indexes
spatial columns (I'm pretty sure this doesn't work with InnoDB)
Very fast for primary read/append use cases (table locks for updates, deletes, but not for inserts)
Also typically has faster inserts
caches indexes in memory (key buffer), but relies on the OS to buffer the actual data pages
For example, I'd use InnoDB for things like ecommerce, user databases or anything that I want to use transactions in.
For data warehouses, logging, reporting, etc I'd probably use MyISAM.
I had to list some advantages of MyISAM over InnoDB
FULLTEXT search
...
no, that's it.
(OK, there are some cases where MyISAM is faster than InnoDB, but rarely enough that it's worth putting up with the lack of ACID-compliance. Today the main reason for doing anything with MyISAM is to get fulltext search which is sadly not supported in InnoDB.)
I am not sure if this is no longer true MyISAM is faster than InnoDB for reads.
Also, MyISAM tables are stored in separate files and (from what I can remember) you can actually transport those files to another MySQL database and is easier to backup.
By default InnoDB databases are stored in one huge glob on the file system.
As for why it is still being widely used, I always figured it was because it is the default option. Personally, I still believe that the advantages of InnoDB triumphs MyISAM and MyISAM also has problems with data integrity from my experience.
You certainly could create InnoDB tables without foreign keys, but that is cutting out one of the main advantages of it: referential integrity.
However, since MyISAM isn't built with the intent of referential integrity table keys can be stored differently, and perhaps more efficiently.
There are also some differences in locking and access. InnoDB supports row level locking, whereas MyISAM only supports table-level locking. Depending on the queries you're performing (SELECTS versus INSERTS/UPDATES) this can have a noticeable effect on performance.
You prolly need to read up on the Mysql Peformance blog.