keep and remove PK indexes to improve query performance, and why? - mysql

I am trying to optimize a few stored procedures in a MySQL database. A few columns have more than one index. These columns are used in joins and WHERE clauses.
Which do I keep and which do I remove to improve query performance, and why?
select table_name,index_name,seq_in_index,column_name,non_unique,index_type,comment from information_schema.statistics
where table_name in('suspicious_activity_report','customer_comment_table','employement_status','Country_Master','Country_Master')
order by table_name,column_name

Your query's output shows tables from all the databases on your system. You need to show which database each table is in, like this:
select table_schema, table_name, index_name, seq_in_index,
column_name, non_unique, index_type, comment
from information_schema.statistics
where table_name in( 'suspicious_activity_report',
'customer_comment_table',
'employement_status',
'Country_Master')
order by table_schema, table_name, seq_in_index;
You can also say WHERE ... table_schema = DATABASE() if you want to show information from only the current database.
This will remove the apparently duplicated indexes from your output.
Multi-column indexes are often added to tables to handle specific query patterns. Your output shows only one multicolumn index: country_master(Country_ID, Client_ID). This index is suitable for these patterns, among a few others.
WHERE Country_ID = <constant> AND Client_ID = <constant>
WHERE Country_ID = <constant> AND Client_ID BETWEEN <constant> AND <constant>.
Like #P.Salmon said, before you remove indexes, you need to figure out which query patterns use them. You could do this by removing them in production and observing where performance collapses. But that's unwise and will anger your users.

Related

Count query from different databases with same schema

Is there any simple way to get count data of single table from different databases(db names) with same schema.
I tried like this..
SELECT COUNT(id) AS db1users,
(SELECT COUNT(id) FROM DB2.users) AS db2users,(
SELECT COUNT(id) FROM DB3.users) AS db3users,
(SELECT COUNT(id) FROM DB4.users) AS db4users,
..........
..........
..........
FROM DB1.users;
I got the exact result but query becoming very large. Is there any simple way to get this..
Please help
Another option, that avoids the need for dynamic sql (and is far less expensive, hence much more scalable), would be to use MySQL the INFORMATION_SCHEMA.TABLES table. It has a column named TABLE_ROWS, whose specification is as follows:
TABLE_ROWS
The number of rows. Some storage engines, such as MyISAM, store the exact count. For other storage engines, such as InnoDB, this value is an approximation, and may vary from the actual value by as much as 40% to 50%. In such cases, use SELECT COUNT(*) to obtain an accurate count.
If this matches your requirement, then you can use a simple query loke:
SELECT table_schema, table_rows FROM information_schema.tables WHERE table_name = 'users'
The best way to do this would be via a scripting language (e.g. Python, Ruby, PHP); you'd execute a database query to get all the database names from your database, then create a SQL statement with all your select count(id) from...; once you've built the SQL statement, you'd execute it.
You can also do this in dynamic SQL inside MySQL; dynamic SQL is hard to write and debug, so I'm not a huge fan....

Select distinct index names

I need to select all indexes from a given table.
But, it looks like MySQL creates multiple indexes with the same name with all the possible column combinations when there is more than one column in the index.
So SHOW INDEXES returns multiple times the same value.
Is there a way to do a select distinct to get the index names from a given table?
And if possible that is not MySQL specific.
Please try this query:
SELECT DISTINCT INDEX_NAME FROM information_schema.statistics
WHERE table_schema = 'your_schema'
AND table_name = 'your_table'

difference in DataBases

How to make query to information_schema.tables to get list of available tables which is exist in one DB but not exist in another one, something like diff but more suitable. I just need sql query.
So i have Db's like A,B,C,D and all these DB's should has the same tables, how I can check it ?
try
select *
from INFORMATION_SCHEMA.tables
group by table_name
having count(table_schema) < 4
if you have 4 DB's. If more you have to adjust the having clause.
This query give you all unique tables in all databases.
SELECT *,count(TABLE_NAME)
FROM
`TABLES` group by table_name
having count(TABLE_NAME)=1
And if you want repeated table names then use this
SELECT *,count(TABLE_NAME)
FROM
`TABLES` group by table_name
having count(TABLE_NAME)>1

(My)SQL: Wildcard in FROM clause?

I have a database with about 200 tables, and need to do a query on all tables containing a certain column (creation_date), but not all tables have that column. SELECT * FROM * WHERE creation_date>=42 obviously doesn't work, but what would be the best way of doing it?
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, TABLE_NAME,
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tbl_name'
[AND table_schema = 'db_name']
[AND column_name ='creation_date']
copied directly from MySQL - you need to loop thru these system tables and the list will contain those ...
then you can build your SQL statements and be sure that they work ...
You could build a dynamic SQL query from metadata. I would approach this like:
Get a list of tables
For each table,
See if the table has the column creation_date
If it does, add your query on this table to the dynamic query
Union the results together
You might also be able to create a view on the multiple tables. Then you can just query the view.
You can try to include the table you want to query like so:
SELECT * FROM table1 a, table2 b WHERE a.creation_date>=42
You cannot use a wildcard in the from. In the way as shown above you can specify on which tables the where clause must apply. You can than leave out the ones that don't have the column.
So in the example query, table1 (alias a) has the column, and table2 (alias b) does not.

How to get the total numbers of rows stored in the MySQL database table?

Is there a MySQL command to count the number of rows in a table, and if so, what is it?
MySQL COUNT() function
SELECT COUNT(*) FROM table
A nice way to get AN ESTIMATE of the number of rows can be via meta-data information in the information_schema tables.
Note, this is just an ESTIMATE used for query optimizations.
There may be a way to get exact # of rows from the information_schema, but I am not 100% sure if this is possible.
SELECT table_schema, table_name, table_rows
FROM information_schema.tables
ORDER BY table_rows DESC
This gives you the number of rows from a specific table name that you set:
SELECT TABLE_ROWS from information_schema.TABLES where table_name = "your_specific_table_name_here";