MySql Group By Use Index - mysql

If i have a table in Mysql which has a multi column index on the fields (phone_number, name)
While querying this table if i just group by on phone_number will this index be used?
And if i performing any operation involving just phone_number will the index be used?
And if i want to group by phone_number, name then will this index be used?

In some cases, MySQL is able to perform GROUP BY using index access.
the preconditions for using indexes for GROUP BY are that all GROUP
BY columns reference attributes from the same index, and that the
index stores its keys in order.
this mean that in your case is possibile use index for both your question
You can find more here http://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html

Related

Should I begin a MySQL index with unique or non-unique field?

The problem I have is the following:
I have a table that contains about 100000000 rows
it has 22 fields - some numeric, some text
it has a primary key id (auto-incremented integer)
it has a field another_id of type bigint, and a unique key on it
it has a field called state that can take only 4 integer values (0 to 3)
I need that the queries of the following form are executed as fast as possible:
SELECT COUNT(*)
FROM my_table
WHERE another_id IN ( <about 100 values> )
AND state = ...
for different values of state.
How should the index look like? I was thinking about two options:
KEY another_id:state (another_id, state)
KEY state:another_id (state, another_id)
Is there any difference in performance between those two variants? Is there anything else to consider?
Edit: engine is InnoDB
For the query you show, you should create the index with state, another_id in that order.
Define the index with any columns referenced in equality conditions first, after them add one column referenced in a range condition or ORDER BY or GROUP BY.
You may also like my answer to Does Order of Fields of Multi-Column Index in MySQL Matter or my presentation How to Design Indexes, Really, or the video.
I agree with the answer above. One clarification though is that you want to have ita hash index not btree index. It should work faster. The hash index wouldn't work well with any queries that involve inequality such as <=

Using two single-column indexes in where and orderby clause

I have googled a lot and couldn't find a clear answer to my question
assume we have this query
SELECT * WHERE user_id = x ORDER BY date_created
If we have a single column index on user_id and another one on date_created, does the optimizer use both indexes? or just user_id index?
This is your query:
SELECT *
FROM mytable
WHERE user_id = 123
ORDER BY date_created
If you have two distinct indexes, then MySQL might use the index on user_id to apply the where predicate (if it believes that it will speed up the query, depending on the cardinality of your data, and other factor). It will not use the index on date_created, because it has no way to relate the intermediate resultset that satisfy the where predicate to that index.
For this query, you want a compound index on (user_id, date_created). The database uses the first key in the index to filter the dataset: in the index B-tree, matching rows are already sorted by date, so the order by operation becoms a no-op.
I notice that you are using select *; this is not a good practice in general, and not good for performance. If there are other columns in the table than the user and date, this forces to database to look up at the table to bring the corresponding rows after filtering and ordering through the index, which can be more expensive than not using the index at all. If you just need a few columns, then enumerate them:
SELECT date_created, first_name, last_name
FROM mytable
WHERE user_id = 123
ORDER BY date_created
And have an index on (user_id, date_created, first_name, last_name). That's a covering index: the database can execute the whole query using on the index, without looking up the table itself.

using non index with composite index

I have question if I have tables with 3 columns (firstname, lastname , address ) as string/varchar(255)
and I have composite my_idx with 2 columns
CREATE INDEX my_idx ON my_table (firstname,lastname)
if I use sql , will it use my defined index ?
select * from my_table where address="zzz" and firstname="xxxx" and lastname="yyyy"
or should I use index columns as first left most condition
select * from my_table where firstname="xxxx" and lastname="yyyy" and address="zzz"
Thank you
First of all: if you prepend your Query with the keyword "EXPLAIN" it will print out all the indices it may use and which one MySQL choose.
From my understanding, yes it will use the index. The order of the fields in the Query is not relevant.
What matters is the order in the Index, but only if you are not providing all fields in the Query (or applying a function to the value or using e.g. the like operator for the rest of a string). If for example you only queried for lastname, the index can not be used. If you only queried for firstname, the index will be used. If you queried for firstname and address, the index will be used and so on...

How MySQL handles IN predicates

Suppose the table T has three columns,
id int not null auto_increment,
my_id int,
name varchar(200).
and the query is "select * from T where my_id in (var_1, var_2, ..., var_n) and name = 'name_var'".
Is there any performance difference between below two indices?
Index1: (my_id, name)
Index2: (name, my_id).
•Index1: (my_id, name)
•Index2: (name, my_id).
Yes, above two would slightly differ when it comes to query performance.
Always, the leftmost fields are the most important in determining the efficiency and selectivity of an index.
index should be built on the column(s) which are frequently used in the WHERE, ORDER BY, and GROUP BY clauses.
Hope this helps!
In a composite index, the column to be searched should appear first. So, if you are searching for a set of id values, you'll want id to show up first in the index.
But if id is the primary key and you're using a SELECT * clause to retrieve the whole row, it doesn't make sense to add another index. The way tables are organized, all the data of the row appears clustered with each id value. So just use the index on the primary key.
tl;dr: neither (id,name) nor (name,id) will help this query.
In general, it is best to start the INDEX with the WHERE clauses with col = const. One range can come last. IN is sort of like =, sort like a range. Hence, this is best:
INDEX(name, id)
Think of it this way. The index is an ordered list. With this index, it will start at the name=... and then have to scan or leapfrog through all the ids with that name.
I suspect the PRIMARY KEY is not (id). If it were, why would you be checking the name?

MySQL Index + Query Processing

Assume I have this table:
create table table_a (
id int,
name varchar(25),
address varchar(25),
primary key (id)
) engine = innodb;
When I run this query:
select * from table_a where id >= 'x' and name = 'test';
How will MySQL process it? Will it pull all the id's first (assume 1000 rows) then apply the where clause name = 'test'?
Or while it looks for the ids, it is already applying the where clause at the same time?
As id is the PK (and no index on name) it will load all rows that satisfy the id based criterion into memory after which it will filter the resultset by the name criterion. Adding a composite index containing both fields would mean that it would only load the records that satisfy both criteria. Adding a separate single column index on the name field may not result in an index merge operation, in which case the index would have no effect.
Do you have indexes on either column? That may affect the execution plan. The other thing is one might cast the 'x'::int to ensure a numeric comparison instead of a string comparison.
For the best result, you should have a single index which includes both of the columns id and name.
In your case, I can't answer the affect of the primary index to that query. That depends on DBMS's and versions. If you really don't want to put more index (because more index means slow write and updates) just populate your table with like 10.000.000 random results, try it and see the effect.
you can compare the execution times by executing the query first when the id comes first in the where clause and then interchange and bring the name first. to see an example of mysql performance with indexes check this out http://www.mysqlperformanceblog.com/2006/06/02/indexes-in-mysql/
You can get information on how the query is processed by running EXPLAIN on the query.
If the idea is to optimize that query then you might want to add an index like:
alter table table_a add unique index name_id_idx (name, id);