![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
If I have a query: select * from table1 where x=somevalue or x=someothervalue GROUP BY x it would make sense to have an index on 'x' |
|
and if I have: select * from table1 t1, table2 t2 where (t1.x=somevalue or t1.x=someothervalue) and t2.y=t1.x GROUP BY t1.x it would make sense to have an index on 't1.x' and an index on 't2.y' |
|
The reason I ask is because, when I do an EXPLAIN on the query I get 'Using temporary; Using filesort' |
#3
| |||
| |||
|
|
The reason I ask is because, when I do an EXPLAIN on the query I get 'Using temporary; Using filesort' This is for the GROUP BY. I cannot see why you have such a clause. |
#4
| ||||
| ||||
|
|
Maybe I should include my real world example... EXPLAIN SELECT * FROM table1 AS t1 WHERE t1.enabled =1 AND t1.deleted =0 AND t1.score >=50 ORDER BY t1.date_created DESC LIMIT 0 , 15 I get id |select_type|table|type|possible_keys|key|key_len| ref|rows|Extra 1|SIMPLE|t1|range|idx_trust_score|idx_score|1|NULL |52138|Using where; Using filesort |
|
The index is "enabled,deleted,score,date_created" |
|
In this case, can I get rid of the "Using where; Using filesort"? |
|
the ref is NULL, is that good/bad? |
#5
| |||
| |||
|
|
The index is "enabled,deleted,score,date_created" The index idx_score (picked for the query) is on those 4 fields? I bet it's not. Seems like `enabled` and `deleted` are 0|1 fields, |
|
so an index is not selective. The optimizer guesses that `score` is most selective and that it has to scan 52138 rows. |
|
In this case, can I get rid of the "Using where; Using filesort"? You might get rid of the "using where" which means that additional filtering is done on the rows read from the index. I.e. you could force the use of that 4-part index you mention above. |
#6
| ||||
| ||||
|
|
EXPLAIN SELECT * FROM table1 AS t1 WHERE t1.enabled =1 AND t1.deleted =0 AND t1.score >=50 ORDER BY t1.date_created DESC LIMIT 0 , 15 I get id |select_type|table|type|possible_keys|key|key_len| ref|rows|Extra 1|SIMPLE|t1|range|idx_trust_score|idx_score|1|NULL |52138|Using where; Using filesort Hint: this is much better readable in vertical form. End your EXPLAIN query with \G instead of ; to get it. The index is "enabled,deleted,score,date_created" The index idx_score (picked for the query) is on those 4 fields? I bet it's not. |
|
Seems like `enabled` and `deleted` are 0|1 fields, so an index is not selective. |
|
The optimizer guesses that `score` is most selective and that it has to scan 52138 rows. |
|
In this case, can I get rid of the "Using where; Using filesort"? You might get rid of the "using where" which means that additional filtering is done on the rows read from the index. I.e. you could force the use of that 4-part index you mention above. "using filesort" is not necessarily bad. It just means that the result will be sorted. If it fits into sort_buffer, then no file will be touched. For small results this sorting pass is no issue. |
#7
| ||||
| ||||
|
|
The index is "enabled,deleted,score,date_created" The index idx_score (picked for the query) is on those 4 fields? I bet it's not. Seems like `enabled` and `deleted` are 0|1 fields, yes, the index is on those 4 fields. enabled, deleted and score are tinyint(3) date_created is an int(14). |
|
id |select_type|table|type |possible_keys |key |key_len|ref |rows |Extra 1 |SIMPLE |t1 |range|idx_trust_score|idx_score|1 |NULL|52138|Using where; Using filesort |
|
so an index is not selective. The optimizer guesses that `score` is most selective and that it has to scan 52138 rows. Note sure I understand by most selective. I want a score >= 50, not sure I understand what you mean by having to 'guess'. |
|
In this case, can I get rid of the "Using where; Using filesort"? You might get rid of the "using where" which means that additional filtering is done on the rows read from the index. I.e. you could force the use of that 4-part index you mention above. Sorry, but I am afraid I also don't understand what you mean. |
#8
| |||
| |||
|
|
The optimizer guesses that `score` is most selective and that it has to scan 52138 rows. I don't see why it would guess that `score` is more selective than (enabled, deleted, score), which it can get on a range-select from the given index. |
#9
| |||
| |||
|
|
I don't see why it would guess that `score` is more selective than (enabled, deleted, score), which it can get on a range-select from the given index. I agree. An index on (enabled,deleted,score) should be more useful for the query than an index on (score) alone. Except when the distribution of `enabled` and `deleted` values is pathological. |
|
But the MySQL optimizer is known to to have ... deficites ... when it comes to estimating the selectiveness of a compound index. |
|
There might be another reason why the optimizer picks the index on (score) - this index is smaller. So even if there are more index entries to be scanned, it could be fewer index pages being read from disk. |
![]() |
| Thread Tools | |
| Display Modes | |
| |