Reputation: 8474
I have the following query:
select min(a) from tbl where b > ?;
and it takes about 4 seconds on my mysql instance with index(b, a)
(15M rows). Is there a way to speed it up?
Explain:
explain select min(parsed_id) from replays where game_date > '2016-10-01';
id: 1
select_type: SIMPLE
table: replays
partitions: NULL
type: range
possible_keys: replays_game_date_index,replays_game_date_parsed_id_index
key: replays_game_date_parsed_id_index
key_len: 6
ref: NULL
rows: 6854021
filtered: 100.00
Extra: Using where; Using index
Index statement:
create index replays_game_date_parsed_id_index on replays (game_date, parsed_id);
Upvotes: 0
Views: 104
Reputation: 142208
This may or may not help: Change the query and add an index:
SELECT a FROM tbl WHERE b > ? ORDER BY a LIMIT 1;
INDEX(a, b)
Then, if a matching b
occurs soon enough in the table, this will be faster than the other suggestions.
On the other hand, if the only matching b
is near the end of the table, this will have to scan nearly all the index and be slower than the other options.
a
needs to be first in the index. By having both columns in the index, it becomes a "covering" index, hence a bit faster.
It may be that using my SELECT
, together with two indexes will give the Optimizer enough to pick the better approach:
INDEX(a,b)
INDEX(b,a)
Schema
Adding either (or both) composite indexes should help.
Shrinking the table size is likely to help...
INT
takes 4 bytes. Consider whether a smaller datatype would suffice for any of those columns.DATETIME
, TIMESTAMP
); do you need all of them?fingerprint varchar(36)
a UUID/GUID? If so, it could be packed into BINARY(16)
.640MB is tight -- check the graphs to make sure there is no "swapping". (Swapping would be really bad for performance.)
Upvotes: 0
Reputation: 48770
I think the index MySQL is using is the right one. The query should be instantaneous since a SINGLE read from the index should return the result you want. I guess for this query MySQL's SQL optimizer is doing a very poor job.
Maybe you could rephrase your query to trick the SQL optimizer onto using a different strategy. Maybe you can try:
select parsed_id
from replays
where game_date > '2016-10-01'
order by parsed_id
limit 1
Upvotes: 1
Reputation: 1269443
Is this version any faster?
select @mina
fro (select (@mina := least(@mina, a)) as mina
from tbl cross join
(select @mina := 999999) params
where b > ?
) t
limit 1;
I suspect this won't make much difference, but I'm not sure what happens under the hood with such a large aggregation function running over an index.
Upvotes: 0