InnoDB to MyISAM conversion strange performance behaviour - mysql

this may be a very trivial question but i dont understand it, because afaik MyISAM should be faster
i have a database containing all MyISAM tables except one - it's simple N:M joining table with ~130k records. i dont know why only this table is InnoDB, but it wasnt intentional :) It has indexes on both foreign keys pointing to its associated tables.
I tried to change the table to MyISAM, cause i tought it would boost the performance, but instead, queries involved this table was like 50x slower (i even tried to recreate the indexes, but it didnt help). Why is that?

I suspect your replacement indexes aren't getting used. Have you tried analysing the query plan with EXPLAIN? This should show you whether your indexes are being used, and how.
Just enter "EXPLAIN [yourquery];" into the MySQL console.

Related

In Mysql, why do unused indexes affect the query plan?

I've seen this several times but I could be misinterpreting the EXPLAIN query plan.
Suppose I have a table(col1, col2).
I want to join it with another table on both col1 and col2.
So I create an index(col1, col2).
Sometimes, the EXPLAIN shows that the index is not being used. Perhaps some other inefficient index is used or none at all.
But if I create another index(col1), then the first index(col1, col2) is used.
Has anyone ever had this happen to them before? Do you have any idea why this might happen?
My theory is that the unused index provides some more accurate statistics about the table that hints to the query plan to use the first index. But I'm not familiar enough with the inner workings of mysql to know if this is true or how to prove it.
The documentation of MySQL for ALTER TABLE states that it may be required to run ANALYZE TABLE on it to refresh the index cardinality, which I believe to be a factor in the behaviour you're seeing. Also, the query optimiser usually handles empty (or near) empty tables quite different from populated tables, and it'll often do a full table scan instead of using an index when there are only a few rows. For my own development at $work I can't rely on the EXPLAIN output of my dev database because of that.

How do I clear the MySQL Query Planner's statistics

I have a number of complex queries that I'm trying to benchmark. It was discovered that on one production box that the query planner hadn't been updated which is likely the cause of some of the poor performance we were seeing (MyISAM tables). To be clear, all indexes on the table are showing with NULL cardinality.
Of course, I need to perform an ANALYZE TABLE on my production boxes, but I'd like to somehow benchmark the performance of my queries in a dev environment before I do that. My dev environment shows good, usable indexes on the table. I'd like to.. "UNANALYZE" the table so I can compare the performance of the broken indexes we have in production versus what we should expect with proper indexes. Would just deleting the index give me the same results, or is there a better way to just flush the statistics?
BTW, I recognize that the NULL cardinality is an obvious problem and easy to fix. However, I'd like to quantify how much this has been hurting the performance. You know.. for science!
You could not, AFAIK, but you could play with FORCE_INDEX() clause on your SQL statement to force usage of an inadequate index, and then MySQL will fallback to table scan ;)

MySQL - InnoDB vs MyISAM

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

Does this case call for InnoDB or MyISAM?

I'm doing a search on a table (few inner joins) which takes max 5 seconds to run (7.5 million rows). It's a MyISAM table and I'm not using full-text indexing on it as I found there to be no difference in speed when using MATCH AGAINST and a normal "like" statement in this case from what I can see.
I'm now "suffering" from locked tables and queries running for several minutes before they complete because of it.
Would it benefit me at all to try and switch the engine to InnoDB? Or does that only help if I need to insert or update rows... not just select them? This whole table-locking thing is busy grinding my balls...
InnoDB supports row-level locking instead of table-level locking... so that should alleviate your problem (although I'm not sure it will remove it entirely).
Your best bet would be to use a dedicated search system (like Sphinx, Lucene, or Solr)
The difference between row-level and table-level locking is only important for insert and update queries. If you're mostly do selects (so the inserts/updates do not happen too often to lock the table) the difference will not be all that much (even though in recent benchmarks InnoDB seems to be outperforming MyISAM).
Other ways you could think about is to reorganise your data structure, perhaps including additional lookup table with 'tags' or 'keywords'. Implementing more efficient full text engine as suggested by webdestroya.
Last but not least, I'm also surprised that you got similar results with FULL TEXT vs LIKE. This could happen if the fields you're searching are not really wide, in which case maybe a stndard B-TREE index with = search would be enough?

Mysql FULLTEXT index, search locks table

Consider this scenario, my database table has 300000 rows and has a fulltext index. Whenever a search is done it locks the database and doesn't allow anyone else to login to the portal.
Any advice on how to get things sorted out here will be really appreciable.
Does logging on perform a write to the table? eg. a 'last visit' time?
If so you may expect behaviour something like this because MyISAM writes do a lock over the entire table. Usually this is avoided by not using noddy MyISAM and going to InnoDB instead, which has row-level locking (amongst other desirable database features).
The problem, of course, is that you only get fulltext search with MyISAM.
So you'll need to split your tables up. If you can keep the read-heavy and fulltext stuff in a different table to the stuff that needs writing (but linked using the same primary key), you can probably make it so that the two operations don't affect each other.
Better, migrate the bulk of the table to InnoDB, leaving only a fulltext field in MyISAM. Everything except fulltext searches can then steer clear of the MyISAM table, and use only the InnoDB table which exhibits much better locking performance. Personally, I now tend to store everything in the InnoDB table, including the text, and store a second copy of the text in the MyISAM table purely for fulltext searchbait purposes; this simplifies queries and code and brings the advantages of InnoDB's consistency to the text content, and I also use it to process the searchbait to get stemming and other features MySQL's fulltext doesn't normally support. But it does mean you have to spend a lot more space on storage.
You can also improve matters by cutting down number of writes. For example if it is a 'last visit' timestamp you're writing, you can avoid writing that unless, say, a minute has passed between the previous time and now, on the basis that no-one needs to know the exact second someone last accessed the site.
If you use an external search engine or MySQL search plug-ins Lucene or Sphinx, they should be able to read and index without locking the table. They store a local version of the indexed records, so they don't have to read the table very often, and never need to write to it.