There are maybe several hundred writes a day, versus the tens of thousands of reads. My databases are located on an SSD drive.
Based on this statement, let's play with some numbers. Lets's say there are 500 writes a day and 20,000 reads a day. That computes out to the following
- 97.56% reads per day
- 2.44% writes per day
- 40 reads / write
As much as I love InnoDB, I would have to choose MyISAM in this case for several reasons
REASON #1
You only have 150MiB of MyISAM tables (70MiB Data, 80 MiB Indexes)
REASON #2
InnoDB indexes tend to get very bloaty because Secondary Indexes have keys into the Clustered Index. This always results in a double index lookup. This can be overlooked with large, write-heavy datasets.
REASON #3
InnoDB tablespaces tend to get very bloaty because of MVCC being created and discarded without an automatic reclaiming of disk space:
All this can be avoid with MyISAM
REASON #4
InnoDB protects individual rows by performing MVCC for transaction control. The overhead generated for reads in a day would probably be greater than 150 MiB.
I can probably name 2 or 3 more reasons, but let's cut to the chase: Is there anything that can improve performance for MyISAM in your case? Why, yes there is.
Your said the following
The table is about 260k rows in size, with 28 fields which for the most part is varchars and ints
If you have many varchars, there is something you can do to increase read/write performance. For any MyISAM table mydb.mytable
: run this command:
ALTER TABLE mydb.mytable ROW_FORMAT=Fixed;
What will this do, this will treat all VARCHARs as CHARs. Every row will be the exact same length. This will increase disk space 80%-100%. In your case, let's assume it doubles your 150 MiB MyISAM table to 300 MiB. Where is the benefit? Your MyISAM table can now be read/written anywhere from 20% - 30% faster without changing anything else I learned that from pages 72,73 from MySQL Database Design and Tuning.
I have written about this in the past:
Here is something to really think about
MyISAM only caches indexes, so there is always disk I/O. InnoDB caches data and indexes. If you could guarantee that every query you call against this one table can only be fetch necessary columns and all columns can be fetched from the index only (called a covering index)
Here are some nice links on Covering Indexes:
MyISAM can do shared reads. So can InnoDB.
Please remember that MyISAM inserts, updates, and deletes perform full tables locks each time (that can be the critical path for disk I/O in making InnoDB wait its turn in certain circumstances). If the table is ready-heavy, you may want to use a dedicated MyISAM key cache.
Heavy INSERTs from LOAD DATA INFILE
will lock the MyISAM table. InnoDB can tolerate it better but check the behavior of LOAD DATA INFILE
to see if it locks the table regardless of Storage Engine.
The tradeoff depends upon how often you write to the MyISAM table.
PLEASE DO NOT JOIN THE MyISAM TABLE TO ANY INNODB TABLE !!! The locking is clumsy and MyISAM changes cannot rollback.
Best Answer
Inserting into a MyISAM table may take a table lock on that table. Since that
INSERT
is coming from a Trigger on a InnoDB table, it is inside a transaction. So, if the table lock takes a long time, the transaction takes a long time, hence "lock wait timeout".The exception on the table lock is if there have been no updates or deletes from the MyISAM table and the PK is
AUTO_INCREMENT
. (Or something like that. Dig in the docs for the specifics.)Is it possible to add to
audit
outside the InnoDB transaction?You say "full table lock requests" -- which table? What is the specific text?
Another thing that can mess up inserting a MyISAM table -- a big
SELECT
. Perhaps you do a big 'report' twice a day?Rethink whether to use MyISAM for
audit
.