What i want to ask, if we define relations, one-to-one, one-to-many etc will that increase the performance in comparison to if we dont create relations but do join the table on the go like
select * from employee inner join user on user.user_id = employee.user_id
i know this question has been asked before and most answers i have got saying that performance don't get affected by not using relations.
But i have also heard that creating indexes makes the query faster, so is it possible to create indexes on tables for foreign keys without creating relations. I'm little confused about index.
and what if we have large database like 100+ tables plus alot of records will the relations matter in terms of database query performace??
im using mysql and php..
Foreign keys are basically used for data integrity.
Of course, indexing boosts performance.
Regarding the performance with or without foreign keys, when it's said they improve performance is because when you define a foreign key you are implicitly defining an index. Such an index is created on the referencing table automatically if it does not exist.
Relations are used to maintain the referential integrity of the database. They do not affect performance of the "select" query at all. They do reduce performance of "insert", "update" and "delete" queries, but you rarely want a relational database without referntial integrity.
Indexes are what makes the "select" query run faster. They also make insert and update queries significantly slower. To know more about how the indexes work go to use-the-index-luke. This is by far the best site about this topic that I have found.
That said, databases usually make indexes automatically when you declare a primary key, and some of them (MySql in particular) make indexes automatically even when you define a foreign key. You can read all about why they do that on the above site.
Related
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'm experimenting with various indexing settings for my mysql database.
I wonder though, by removing or adding indexes is there any possibility to damage data rows in any way? Obviously I realise that if I make any application queries fail, that can cause bad rows. I'm more talking just about the structural queries themselves.
Or will I simply affect the efficiency of the database?
I just want to know if I have safety to experiment or if I have to be cautious?
The data isn't in phpmyadmin, it's in mysql. Adding/removing an index will not affect your data integrity by default. With a unique index, and using the ignore keyword it can.
That said - you should always have a backup of your data, it's easy to run a test like:
CREATE TABLE t1 LIKE t;
INSERT INTO t1 SELECT * FROM t;
ALTER TABLE t1 CREATE INDEX ...;
Then compare the difference in tables (perhaps a COUNT is fine in your case).
Adding/removing indexes is safe in terms of the rows in your table. However as you note, too many indexes or poorly constructed indexes can be (very) detrimental to performance. Likewise, adding indexes on large tables can be a very expensive process, and can bring a MySQL server to its knees, so you're better off not "experimenting" on production tables.
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.
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".
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.