What is the best practice to improve table performance? - mysql

In order to maintain tables and indexes efficiency it is not recommended to directly run "OPTIMYZE TABLE" (as stated in the link below), so is it best practice to do so in the following exact order?
DROP foreign keys (in order to drop related indexes)
DROP indexes (composite and non composites)
Perform OPTIMIZE TABLE
ADD INDEXES
ADD FOREIGN KEYS
ANALYZE TABLE
I believe this last step (analyze table) is also useful in order to update indexes cardinality within the information_schema.statistics table.
Any correction or further suggestions on this are welcome!
Thanks
link: https://www.percona.com/blog/2010/12/09/mysql-optimize-tables-innodb-stop/
example:
alter table T1 DROP index i1 ;
alter table T1 DROP index i2 ;
optimize table T1 ;
alter table T1 ADD index i1(c1) ;
alter table T1 ADD unique index i2(c1, c2) ;
analyze table T1 ;

Did you perceive any improvement? I doubt it. In most situations, InnoDB takes care of keeping its BTrees clean "enough". Running an OPTIMIZE TABLE provides only a minor improvement for a short period of time.
There are other things to look at. Examples:
index i1(c1) is unnecessary since you also have unique index i2(c1, c2).
If you have PRIMARY KEY(id) consider upgrading that unique index to PRIMARY KEY(c1, c2).
FOREIGN KEYs cost something on every insert; do you really need them?
Are you blindly using BIGINT when perhaps SMALLINT would suffice?

Related

SQL Index on foreign key

When I join 2 tables tbl1, tbl2 on column1, where column1 is primary key on tbl1. Assuming that column1 is not automatically indexed should I create an index on both tbl1.column1 and tbl2.column1 or just on tbl2.column1. Are the number of rows of each table affect that choice?
A primary key is automatically indexed. There is no way around that (this is how the "unique" part of the unique constraint is implemented). So, tbl1.column1 has an index. No other index is needed.
As for tbl2.column2, you should probably have an index on that. MySQL does create an index if you explicitly declare a foreign key relationship. So, with the explicit declaration, no other index is necessary. Note: this is not true of all databases.
The presence of indexes does not change the results of queries nor the number of rows in the table, so I don't understand your final question. Indexes implement relational integrity and improve (hopefully!) performance on certain types of queries
Generally yes, because often you'll want to do the reverse of the join at some point.

Does the order of KEYs in a CREATE TABLE statement matter?

Note: I searched around to see if this question has been asked before. All the existing questions I've been able to find are asking about composite index ordering, or the ordering of columns for queries on an existing table.
Say I have the following table:
CREATE TABLE `foobar` (
`foo_id` int(11),
`bar_id` int(11),
KEY `foo_id` (`foo_id`),
KEY `bar_id` (`bar_id`)
);
It has two unrelated indexes on it. If I swap the definition of the two indexes, it might look like this:
CREATE TABLE `foobar` (
`foo_id` int(11),
`bar_id` int(11),
KEY `bar_id` (`bar_id`),
KEY `foo_id` (`foo_id`)
);
If I run SHOW CREATE TABLE foobar on each of these I can see that there is a difference between the ordering of the KEYs for each table. My question is, does the ordering in this specific case matter? I know it would matter if foo_id and bar_id were used together in a composite index, but here they are not.
If it does indeed matter, is there a way to arbitrarily rearrange the keys once the table has been created? (Something akin to ALTER TABLE foobar ADD INDEX foo_id (foo_id) AFTER bar_id, which I'm pretty sure is invalid as written.)
There is no visual representation of the keys, and it would not add any overhead to arrange them in any way. The key-setting function simply adds qualities to existing columns, which can be rearranged.
The only exception I could see to this would be if you went through some IDE (DB Forge, HeidiSQL, SequelPro, etc), which arranged key values to the top of some list they generated. This, however, is on the side of the system which is interpreting it and has nothing to do with the database performance.
No.
All keys are 'equal'. All are considered when deciding which to use. The key that has the least 'cost' is used. ('Cost' is a complicated formula involving the effort to perform the query one way versus another.)
If you are using InnoDB, it is really a good idea to have a PRIMARY KEY.
If your table is a "many-to-many" mapping table, here is further advice:
http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table
A related topic: A "composite" index is one that has multiple columns. (Eg, INDEX(a,b).) The order of the columns does make a difference.
You can use modify in altertable comanad
ALTER TABLE table_name MODIFY foo_id int AFTER bar_id

Why do we usually create an index before dropping the primary key?

I think the following is a standard coding "pattern" when we need to change the primary key of a table to serve better our queries via the index:
ALTER TABLE employees
ADD UNIQUE INDEX tmp (employee_id, subsidiary_id);
ALTER TABLE employees
DROP PRIMARY KEY;
ALTER TABLE employees
ADD PRIMARY KEY (subsidiary_id, employee_id);
My understanding is that the tmp index is created before dropping the primary key in order to facilitate queries using the current primary key and not lose performance.
But I don't understand this.
When we execute an ALTER TABLE (I am referring to the ALTER TABLE to drop the primary key) the table will be locked until the operation finishes right?
So the queries will not be able to run anyway. So why create tmp in the first place?
I haven't seen this pattern. But, I would expect it for a slightly different reason. The purpose is less "facilitating" queries than ensuring that the pair of keys remains unique throughout the entire set of transactions.
In other words, between dropping the primary key and creating the new key, there is a short window of opportunity for someone to insert a duplicate pair of keys. Then the second operation will fail. By creating the unique index first, you prevent this from happening.
If you know there are no other users/queries using the system when you are modifying the table (say you are in single user mode), then there is no need to create the additional index.

How to effeciently create index in mysql

I want to create an Index on Id of my table. It's a bigint.
I would like to know what is the most good to have this index so that I can retrieve the data as fast as possible.
For example :
CREATE INDEX id_index ON lookup (id) USING BTREE;
Wit respect, you're overthinking this. It happens that InnoDB and MyISAM tables only support BTREE indexes. If you have MEMORY table you could create the index USING HASH but this is probably an ordinary table.
CREATE INDEX id_index ON lookup (id);
gets you what you want.

Faster selects when using GUID vs. Select WHERE?

I have a table with thousands of records. I do a lot of selects like this to find if a person exists.
SELECT * from person WHERE personid='U244A902'
Because the person ID is not pure numerical, I didn't use it as the primary key and went with auto-increment. But now I'm rethinking my strategy, because I think SELECTS are getting slower as the table fills up. I'm thinking the reason behind this slowness is because personid is not the primary key.
So my question, if I were to go through the trouble of restructuring the table and use the personid as the primary key instead, without an auto-increment, would that significantly speed up the selects? I'm talking about a table that has 200,000 records now and will fill up to about 5 million when done.
The slowness is due indirectly to the fact that the personid is not a primary key, in that it isn't indexed because it wasn't defined as a key. The quickest fix is to simply index it:
CREATE UNIQUE INDEX `idx_personid` ON `person` (`personid`);
However, if it is a unique value, it should be the table's primary key. There is no real need for a separate auto_increment key.
ALTER TABLE person DROP the_auto_increment_column;
ALTER TABLE person ADD PRIMARY KEY personid;
Note however, that if you were also using the_auto_increment_column as a FOREIGN KEY in other tables and dropped it in favor of personid, you would need to modify all your other tables to use personid instead. The difficulty of doing so may not be completely worth the gain for you.
You can to create an index to personid.
CREATE INDEX id_index ON person(personidid)
ALTER TABLE `person ` ADD INDEX `index1` (`personid`);
try to index your coloumns on which you are using where clause or selecting the coloumns