My team has added these statements with the create tables after the columns are defined:
ENGINE=MyISAM DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC AUTO_INCREMENT=465
The question is the table is a country lookup table. so we know it has a fixed list values of about 275-ish. And this table will be 99% a read only table. Very rare will be any write if i need to update any colunm property.
So do i need all that stuff beyond 'ENGINE=MyISAM DEFAULT CHARSET=utf8'? this is just one table, they have these for all most all tables and i cant understand why lookup tables will have all these commands/
You can look up all those in the CREATE TABLE doc.
You're right though. For the context you describe, they're almost surely completely unnecessary.
Asides
Re: AUTO_INCREMENT as part of your CREATE TABLE -- yeah, that's just because it was part of the SHOW CREATE TABLE of a live table, not because it was part of your teams intentions/ongoing script. No biggie.
Note that CHECKSUM and DELAY_KEY_WRITE are for MyISAM tables only. If that table was InnoDB, the features those two parameters bring are arguably implicitly taken care of (i.e. table integrity and write issues).
Why do we need innoDB for read only lookup tables? I thought innoDB is better for write intensive tables?
Sorry. I didn't mean to imply that you needed InnoDB. It's just a reflex. :)
Wheater or not InnoDB performs better for writing depends on the usage pattern / application. For your context, I wouldn't expect you seeing a performance difference weither you use MyISAM or InnoDB. At any rate, as a rule of thumb, since InnoDB can be acid complient, more resistant to corruption, and stored in memory (in InnoDB's buffer pool) I always advocate for it. MyISAM fails on all those counts.
Related
Back then when i was working heavily with MyISAM Tables i always had a cronjob which ran
~# mysqlanalyze -o database
I know that MyISAM benefit from this in certain ways e.g.: fragmentation and whatnot
Now, when running the same command on a databse where the majority of tables is InnoDB i wonder if this "does any good" to the tables and is considered a good practice to do so every now and then or if its rather counter productive. Reading alot of :
Table does not support optimize, doing recreate + analyze instead
Which sounds expensive with regards to Disk IO / CPU time ?!
would appreciate some input on this.
https://dev.mysql.com/doc/refman/8.0/en/optimize-table.html says:
For InnoDB tables, OPTIMIZE TABLE is mapped to ALTER TABLE ... FORCE, which rebuilds the table to update index statistics and free unused space in the clustered index.
This does do some good in cases when you had too much fragmentation. Pages will be filled more efficiently, indexes will be rebuilt, and disk space occupied by the table will be reduced if you use innodb_file_per_table (which is the default in recent versions).
It does take time, depending on the size of your table. It will lock the table while it's running. It will require extra disk space while it's running, as it creates a copy of the table.
Doing optimize table on an InnoDB table is usually not necessary to do frequently, but only after you do a lot of insert/update/delete against the table in a way that could result in fragmentation.
ANALYZE TABLE is much less impact for InnoDB. This doesn't require building a copy of the table. It's a read-only action, it just reads a random sample of pages from the table and uses that to estimate the number of rows, average size of rows, and it update statistics about the indexes, to guide the query optimizer. This is safe to run anytime, it will lock that table for moment, but that won't be any greater regardless of the size of the table.
Don't bother. InnoDB almost never needs either ANALYZE or OPTIMIZE; don't waste your time unless you have identified a need.
An exception is a FULLTEXT index on an InnoDB table. Such can benefit from DROP INDEX, then ADD INDEX.
If you are "reloading" the table from new data, then the following avoids downtime:
CREATE TABLE new LIKE real;
load `new`
RENAME TABLE real TO old, new TO real; -- fast, atomic
DROP TABLE old;
(Caveat: The above technique probably has issues if there are FOREIGN KEYS.)
Does anybody know, does FK reduce insert/update operations in MySQL?
I use engine INNODB.
Having a FK on a table implicitly creates (and maintains) an index.
When doing certain write operations, the FK's implicit INDEX is checked to verify the existence of the appropriate row in the other table. This is a minor performance burden during writes.
When doing SELECT ... JOIN for which you failed to explicitly provide the appropriate index, the implicit index produced by some FK may come into play. This is a big benefit to some JOINs, but does not require an FK, since you could have added the INDEX manually.
If the FK definition includes ON DELETE or UPDATE, then even more work may be done, especially for CASCADE. The effect of CASCADE can be achieved with a SELECT plus more code -- but not as efficiently as letting CASCADE do the work.
FKs are limited in what they can do. Stackoverflow is littered with question like "How can I get an FK to do X?"
Does any of this sound like "reducing insert/update operations"?
does FK reduce insert/update operations in MySQL?
It's not about MySQL but yes it does. Creating FK on a column will create a secondary index and thus upon DML operation those indexes needs to be updated as well in order to have a correct table statistics. So that, DB optimizer can generate a correct and efficient query plan
I read that Innodb is better to use on a table that get a lot's of insert records simultaneously. My application gets about 50 records per seconds. So for these tables should I use Innodb, right?
In the other hand i have some tables that are only used for select, they get few updated or have few new insert. Is MyIsam faster for select ?
If it's the case, is it better to leave some table with MyIsam and some with Innodb or should i use all tables with the same engine ?
My application also searches a lot on the tables that i want to pass in Innodb. What should i do ?
you can check these:
Reasons to use MyISAM:
Tables are really fast for select-heavy loads
Table level locks limit their scalability for write intensive multi-user environments.
Smallest disk space consumption
Fulltext index
Merged and compressed tables.
Reasons to use InnoDB:
ACID transactions
Row level locking
Consistent reads – allows you to reach excellent read write concurrency.
Primary key clustering – gives excellent performance in some cases.
Foreign key support.
Both index and data pages can be cached.
Automatic crash recovery – in case MySQL shutdown was unclean InnoDB tables will still
recover to the consistent state- No check repair like MyISAM may require. All updates have to pass through transactional engine in
InnoDB, which often decreases - performance compared to
non-transactional storage engines.
quoted from here
and for the last part:
REMEMBER! It's OK to mix table types in the same database! In fact it's recommended and frequently required. However, it is important to note that if you are having performance issues when joining the two types, try converting one to the other and see if that fixes it. This issue does not happen often but it has been reported.
quoted from here
I hope that's enough :D
Yes you can, but I'd go with InnoDB only unless there is some serious performance bottleneck
same question on SO
MySQL forum
In short yes you can mix and match to your hearts content.
Keep the following in mind:
InnoDB is ACID complaint. Thus is you need any ACID features use InnoDB. MyISAM is does not support a lot of things like foreign key constraints for example.
Now speed is hard to quantify exactly. Depending on execution paths you might get very big or very small speed differences.
Test and check there is no right or wrong answer here.
I know I should use engine=MEMORY to make the table in memory and engine=INNODB to make the table transaction safe. However, how can I achieve both objectives? I tried engine=MEMORY, INNODB, but I failed. My purpose is to access tables fast and allow multiple threads to change contents of tables.
You haven't stated your goals above. I guess you're looking for good performance, and you also seem to want the table to be transactional. Your only option really is InnoDB. As long as you have configured InnoDB to use enough memory to hold your entire table (with innodb_buffer_pool_size), and there is not excessive pressure from other InnoDB tables on the same server, the data will remain in memory. If you're concerned about write performance (and again barring other uses of the same system) you can reduce durability to drastically increase write performance by setting innodb_flush_log_at_trx_commit = 0 and disabling binary logging.
Using any sort of triggers with temporary tables will be a mess to maintain, and won't give you any benefits of transactionality on the temporary tables.
You are asking for a way to create the table with 2 (or more) engines, that is not possible with mysql.
However, I will guess that you want to use memory because you don't think innodb will be fast enough for your need. I think innodb is pretty fast and will be probably enough, but if you really need it, I think you should try creating 2 tables:
table1 memory <-- here is where you will make all the SELECTs
table2 innodb <-- here you will make the UPDATE, INSERT, DELETE, etc and add a TRIGGER so when this one is updated, the table1 gets the same modification.
as i know the there are two ways
1st way
create a temp table as ( these are stored in memory with a small diff they will get deleted as the session is logged out )
create temporary table sample(id int) engine=Innodb;
2nd way
you have to create two tables one with memory engine and other with innodb or bdb
first insert all the data into your innodb table and then trigger the data to be copied into memory table
and if you want to empty the data in the innodb table you can do it with same trigger
you can achieve this using events also
I'm doing a venue/events database and I've created my tables and would like some confirmation from someone if I did everything right :)
I have 2 tables:
Venues
Events
The primary key of Venues is VENUE_ID, which is set to auto_increment. I have the same column in Events, which will contain the number of the Venue ID. This should connect them, right?
Also, the table engine is MyISAM.
It does not automatically link the tables to each others, and the referenced columns don't necessarily have to have the same name (in fact, there are situations where this is impossible: e.g. when a table has two columns that both reference the same column in another table).
Read up on foreign keys; they're standard SQL and do exactly what you want. Note, however, that the MyISAM storage engine cannot enforce foreign key constraints, so as long as any of the tables involved uses MyISAM, the foreign key declaration doesn't add much (it does, however, document the relationship, at least in your SQL scripts).
I suggest you use InnoDB (or, if that's feasible, switch to PostgreSQL - not only does it provide foreign key constraints, it also has full support for transactions, unlike MySQL, which will silently commit a pending transaction whenever you do something that's not supported in a transaction, with potentially devastating results). If you have to / want to use MySQL, I suggest you use InnoDB for everything, unless you know you need the extra performance you can get out of MyISAM and you can afford the caveats. Also keep in mind that migrating large tables from MyISAM to InnoDB later in production can be painful or even outright impossible.
Your db structure is right.
You can use Innodb for adding foreign key contraints. Also don't forget to add index to the second table for faster joining two tables.
More info about FK http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
Note to comments:
Innodb allows you to make concurrent select/(insert/update) but MyIsam allows you to do the same things if you don't delete from MyIsam table. Otherwise MyIsam will lock your whole table.
Generally, yes. This is how you indicate a one-to-many relation between two tables. You may also specifically encode the relationship into the database by setting up a Foreign Key constraint. This will allow add'l logic such as cascading.