MySQL does FK reduce insert/update operations? - mysql

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

Related

MySql, engine:MyISAM, what index can be used instead of Foreign Key

I am creating a MySQL DB with MyISAM engine. I believe it is not possible to use foreign key with MyISAM. All the tables in DB have primary key, but all of them also need at least 1 FK.
1)Can any of the other options available (apart from PK): such as: UNIQUE, INDEX FULLTEXT or SPATIAL be used instead of FK that serves the same purpose?
2)If the answer to 1) is <0, what else can be done (except changing to InnoDB)?
It smells like you don't understand the purpose of a FOREIGN KEY. It is for one thing:
Referential integrity. But this is not a requirement, it is a feature that you can live without if you write good code.
A FK has a side effect: It builds an INDEX. But the only purpose of an index is:
Faster lookups. This includes WHERE clauses and JOINs between tables.
It is a somewhat common misconception that you need a FK to JOIN two tables. That is totally false. Nor is an INDEX required.
Bottom line...
Get the schema written and your queries written.
When you hit performance problems (which might happen when you have a few thousand rows in a table), look into adding INDEX(es).
Regardless, move to InnoDB.
The answer to your question is no, there is no real alternative in MyISAM.
Depending on your version of MySQL. You could look at before triggers but you would have to write a trigger in place of each foreign key that you would normally create under Innodb. This isn't recommended though, you're reinventing the wheel by doing this and could encounter problems if the logic in the trigger is incorrect. Defeating the purpose.
Unless there's a feature of MyISAM that you can't get with Innodb, I would highly recommend using Innodb and optimizing where necessary.
Hope that helps.
No, MyISAM does not support FK constraints. You can't enforce referential integrity in MyISAM. You could code it yourself using triggers, but this is not recommended.
You can create an index, either unique or non-unique, to provide query optimization for searching or sorting. But this does not provide referential integrity.
ALTER TABLE MyTable ADD INDEX (column1, column2);
or
ALTER TABLE MyTable ADD UNIQUE INDEX (column1, column2);
Don't use a UNIQUE index unless you want the columns to have a unique constraint in addition to the index.
Don't use FULLTEXT or SPATIAL index unless you mean to do fulltext or spatial queries. Those indexes are for those special purposes, and in general they are not interchangeable with ordinary indexes.
And for the record, you should be using InnoDB.

Quick question about relational one-to many database

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.

Index on high write table is bad?

I got an Oracle 9i book from the Oracle publisher.
In it it's written
Index is bad on a table which is updated/inserted new rows frequently
Is it true ? or is it just about Oracle [and not about other RDBMS packages] ?
Edit
I got a table in MySQL like this
ID [pk / AI]
User [integer]
Text [TinyText]
Time [Timestamp]
Only write/read is allowed to this table.
As PK creates Index, is the table design broken ?
If yes, how to solve this type of problem [where AI is the primary key]
This is true with any database to an extent. Whenever indexed columns updated, the index must also be updated. Each additional index adds extra overhead. Whether or not this matters for your specific situation depends on the indices you create and the workload the server is running. Performance implications are best discovered via benchmarking.
Indexes are only for retrieving data. Because they are a pointer to data location(s), INSERT/UPDATE/DELETE statements are slower to maintain the indexes. Even then, indexes can be fragmented because deletion/updating will change -- which is why there are tools to maintain this and table statistics (both are used by the optimizer to determine the EXPLAIN plan).
Keep in mind that indexes are not ANSI -- it's a miracle the syntax & terminology is so similar. But the functionality is near identical between databases that provide it. For example, Oracle only has "indexes" while both MySQL and SQL Server differentiate between clustered (one per table) and non-clustered indexes.
To address your update about the primary key. The primary key is unique, and considered immutable (though it is infact able to be updated, though the value has to be unique to the column). Deletion from the table would fragment the index, which requires monitoring with database vendor specific tools if performance becomes an issue.
It is not that indexes on highly volatile tables are "bad". It's simply that there is a performance impact on the DML operations. I think what the author was trying to say is that you should carefully consider the need for indexes on such active tables.
As in everything computing, it's all about tradeoffs. As #Michael essentially states, "it depends". You might have a high query rate on the table as well, in which the indexes on the table avoid a lot of full table scans. In such a case, your index maintenance overhead may well be worth the benefit derived from the indexes on queries.
Also, I'd probably not buy a 9i book anyway, unless it was a real bargain. I'd recommend you read most anything by Tom Kyte you can get your hands on, especially "Expert Oracle Database Architecture" or "Effective Oracle by Design".

Session / Log tables keys design question

I have almost always heard people say not to use FKs with user session and any log tables as those are usually High write tables and once written data almost always tays forever without any updates or deletes.
But the question is I have colunms like these:
User_id (link a session or activity log to the user)
activity_id (linking the log activity table to the system activity lookup table)
session_id (linking the user log table with the parent session)
... and there are 4-5 more colunms.
So if I dont use FKs then how will i "relate" these colunms? Can i join tables and get the user info without FKs? Can i write correct data without FKs? Any performance impact or do people just talk and say this is a no no?
Another question I have is if i dont use FKs can i still connect my data with lookup tables?
In fact, you can build the whole database without real FKs in mysql. If you're using MyISAM as a storage engine, the FKs aren't real anyway.
You can nevertheless do all the joins you like, as long as the join keys match.
Performance impact depends on how much data you stuff into a referenced table. It takes extra time if you have a FK in a table and insert data into it, or update a FK value. Upon insertion or modification, the FK needs to be looked up in the referenced table to ensure the reference integrity.
On highly used tables which don't really need reference integrity, I'd just stick with loose columns instead of FKs.
AFAIK InnoDB is currently the only one supporting real foreign keys (unless MySQL 5.5 got new or updated storage engines which support them as well). Storage engines like MyISAM do support the syntax, but don't actually validate the referential integrity.
FK's can be detrimental in "history log" tables. This kind of table wants to preserve the exact state of what happened at a point in time.
The problem with FK's is they don't store the value, just a pointer to the value. If the value changes, then the history is lost. You DO NOT WANT updates to cascade into your history log. It's OK to have a "fake Foreign key" that you can join on, but you also want to intensionally de-normalize relevant fields to preserve the history.

mysql create table command add ons question

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.