Can a foreign key use unique index? - mysql

I created a unique index on a column, and then added a foreign key using ALTER TABLE. MySQL added a non-unique index on top of my unique index to the column. Is the non-unique index necessary? Does it speed things up in any way?

Does it speed things up in any way?
First, Indexes do not always speed things up. Indexes are slowing down update, insert and delete statements, because the index has to be updated along with the data.
Second, there are scenarios, where the mysql-optimizer might decide to use a wrong index, and using another Index might be faster.
Is the non-unique index necessary?
No. See also the mysql documentation about YOUR usecase, if you would have done it the other way round:
http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later, if you create
another index that can be used to enforce the foreign key constraint.

Related

Multiple index on same column

I have a table which already have a column with BTREE index on it. Now I want to add a unique key constraint to the same column to avoid race condition from my rails app.
All the reference blogs/article shows I have to add a migration to create a new uniq index on that column like below
add_index :products, :key, :string, unique: true
I want to understand
What happens to BTREE index which is already present?(I need this)
Is it OK to have both the index and they both work fine?
Table has around 30MN entries, will it locks the table while adding index and take huge time to add this UNIQUE index?
You don't need both indexes.
In MySQL's default storage engine InnoDB, a UNIQUE KEY index is also a BTREE. InnoDB only supports BTREE indexes, whether they are unique or not (it also supports fulltext indexes, but that's a different story).
So a unique index is also useful for searching and sorting, just like a non-unique index.
Building an index will lock the table. I suggest using an online schema change tool like pt-online-schema-change or gh-ost. We use the former at my company, and we run hundreds of schema changes per week on production tables without blocking access. In fact, using one of these tools might cause the change to take longer, but we don't care because we aren't suffering any limited access while it's running.
What happens to BTREE index which is already present?(I need this)
Nothing. Creating a new index does not affect existing indexes.
Is it OK to have both the index and they both work fine?
Two indices by the same expression which differs in uniqueness only? This makes no sense.
It is recommended to remove regular index when unique one is created. This will save a lot of disk space. Additionally - when regular and unique indices by the same expression (literally!) exists then server will never use regular index.
Table has around 30MN entries, will it locks the table while adding index and take huge time to add this UNIQUE index?
The table will be locked shortly at the start of the index creation process. But if index creation and parallel CUD operations are executed then both of them will be slower.
The time needed for index creation can be determined only in practice. Sometimes it cannot be even predicted.

What to do with the auto-created index when applying a foreign key constraint in MySQL?

When a foreign key constraint is placed on on a MySQL table, an index is automatically added by MySQL for better performance. I'm totally ok with this. It's all in the docs.
But, when deleting the foreign key, I noticed that the auto-created index itself is not deleted. And that's not in de docs. I'm wondering:
Will it get ever deleted automatically, since MySQL did create it for me too?
How large can a foreign key index get? If it's only a few kilobytes, I'm not bothered, but what if it gets large...?
https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html only says this:
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously.
A foreign key index is just like a regular secondary index. It will grow proportionally to the number of rows in the table, and the data type in the indexed column(s).
It might still be useful to have this index if you run queries that need it. It's common in MySQL deployments to avoid foreign key constraints, but keep the indexes to support optimizing joins or searches.
If you don't need that index, i.e. if you have no queries that use the index, then you can drop it.

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.

Replacing composite key for optimizing performance

I am using mariadb and My sql for different version.I have a table ShellInfo with field ShellID,AuthID,ShellDate,Command.Here the table has composite key to ensure unique record.If the data is huge insertion is taking too much time.
Is there suitable replacement for composite key.

Does MySQL do automatic indexing for foreign keys?

Can anyone tell me if MySQL does indexing for its foreign keys automatically or not?
My MySQL is using MyIsam Engine.
MyISAM does not support foreign keys at all. From the manual:
For storage engines other than InnoDB, MySQL Server parses the FOREIGN
KEY syntax in CREATE TABLE statements, but does not use or store it.
... At a later stage, foreign key constraints will be implemented for
MyISAM tables as well.
This is for MySQL 5.6, the next version, so it is not implemented yet. The text is exactly the same for older versions.
This means that the foreign key construct is not used at all. You can specify it in your CREATE TABLE command but MySQL will silently ignore it. No index will be made out of it, and it won't be stored (so a SHOW CREATE TABLE command will not show that you tried to createa a foreign key).
If you need foreign key support, consider using the InnoDB storage engine instead. InnoDB creates indices automatically for foreign keys.
MyISAM engine doesn't support foreign keys, only the InnoDB engine:
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
InnoDB requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later, if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously.