Mysql multiple columns index - mysql

UPDATE album SET x=1 WHERE store_id=:store_id && type=:type && time<:time
I have a Mysql update query, My question is how can I set up the index for this query
I create index in phpMyadmin, should I select store_id, type, time together and create one index?

if you are searching by store_id and type and time together then yes you can create INDEX for those three.
BUT,
if sometimes you are searching only by store_id then here you should use index only in store_id
if you search by store_id and type then index will be on those two columns.
so it depeneds what are columns you using to search.
here how to use to create what index you want.
ALTER TABLE `album` ADD INDEX `myindex` (`store_id`) --for store_id
ALTER TABLE `album` ADD INDEX `myindex` (`store_id` ,`type`,`time`) --for store_id and type and time
and so on ....
choose which one you want.

When setting up an index, the place to start is the where clause:
WHERE store_id=:store_id && type=:type && time<:time
Start with the equality comparisons. Then you can choose one column for inequality. For this query, the best index would have all three columns:
create index album_storeid_type_time on album(store_id, type, time);

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 <=

Create functions indexes MySQL

I have a table with [date] index.
[date] column:
'2015-01-05'
'2015-01-06'
and etc
Can I create new index for function index?
When i am trying to create it I get error, example:
create index date_y on table (year(date))
If I could we didn't recreate queries for program performance.
Yes and no. No, you cannot create an index on an expression in this fashion. However, if you happen to have mysql v5.7.8 or newer, then you can create generated columns and you can create a secondary index on them (secondary index means that a generated column cannot be part of a primary key).
So, create your expression as a generated column and then create an index on it - if you have mysql v5.7.8 or newer.
One moment, when I have:
date is created index on tableX
id is created index on tableX
id is created index on tableY
My query:
Select * from tableX as x left outer join tableY as y on x.id=y.id
where year(x.date)=2015 and month(x.date)=11
Should I recreate date to:
create index date on tableX (date,id)
or some else?

Optimal MySQL index for search query within date ranges

I have a MySQL table of the form
CREATE TABLE `myTable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`timestamp` datetime NOT NULL,
`fieldA` int(11) NOT NULL,
`fieldB` int(11) NOT NULL,
....
)
The table will have around 500,000,000 rows, with the remaining fields being floats.
The queries I will be using will be of the form:
SELECT * FROM myTable
WHERE fieldA= AND fieldB= AND timestamp>'' and timestamp<=''
ORDER BY timestamp;
At the moment I have two indices: a primary key on id, and a unique key on timestamp,fieldA,fieldB (hashed). At the moment, a select query like the above takes around 6 minutes on a reasonably powerful desktop PC.
What would the optimal index to apply? Does the ordering of the 3 fields in the key matter, and should I be using a binary tree instead of hashed? Is there a conflict between my primary key and the second index? Or do I have the best performance I can expect for such a large db without more serious hardware?
Thanks!
For that particular query adding an index to fieldA and fieldB probably would be optimal. Order of the columns in the index do matter.
Index Order
In order for Mysql to even consider using a particular index on the query the first column must be in the query, so for example:
alter table mytable add index a_b_index(a, b);
select * from mytable where a = 1 and b = 2;
The above query should use the index a_b_index. Now take this next example:
alter table mytable add index a_b_index(a, b);
select * from mytable where b = 2;
This will not use the index because the index starts with a, but a is never used in the query so mysql will not use it.
Comparison
Mysql will only use an index if you use equality comparison. So < and > won't use an index for that column, same with between
LIKE
Mysql does use indexes on the LIKE statement, but only when the % is at the end of the statement like this:
select * from mytable where cola like 'hello%';
Whereas these will not use a index:
select * from mytable where cola like '%hello';
select * from mytable where cola like '%hello%';
Hashed indexes are not used for ranges. They are used for equality comparisons only. Therefore, a hashed index cannot be used for the range portion of your query.
Since you have a range in your query, you should use a standard b-tree index. Ensure that fielda and fieldb are the first columns in the index, then timestamp. MySQL cannot utilize the index for searches beyond the first range.
Consider a multi-column index on (fielda, fieldb, timestamp).
The index should also be able to satisfy the ORDER BY.
To improve the query further, select only those three columns or consider a larger "covering" index.

mysql different query share one index

I have 2 queries
SELECT * FROM table WHERE store_id=1 && album_id=1 && delete=0
UPDATE table SET delete=0 WHERE store_id=1 && album_id=1
I create an index store_id, album_id, delete
my question is can these 2 queries share this index?
or I have to create another index (store_id, album_id) for 2nd one
If you are creating one index that is a composite index as table(store_id, album_id, delete), then both queries should be able to use this index.
THe first will use all three fields in the index because they match the where clause exactly.
The second query will use the first two columns in the index for its where clause.

MySQL - Change index on myIsam table

I have a table where two columns are used in a where condition.
This is a MyIsam table and both columns hold text and use FULLTEXT as index.
The values in both columns are not unique.
The select statement works pretty slow.
Question is: can I simply remove the FULLTEXT index and use another index instead?
The query that is used is just as simple as possbile:
SELECT * FROM tbl WHERE col1=X AND col2=y and col3=z
Thanks!
ALTER TABLE `tableName` DROP INDEX `indexName` ,
ADD INDEX `indexName` ( `ColName` )
This shuld remove the old "FULLTEXT" index and add a "NOT FULTEXT" index.