I have large table with 615 million records in items and 10 thousand in markets
the below query takes 5+ seconds to execute
how can I make it faster. ?
SELECT items.name,items.ID as itemID,items.market_id as market_id,markets.name as marketname
from items,markets
where markets.ID = items.market_id and
items.name like '%bab%'
group by items.name
order by items.name ASC
limit 0,10
Explain
-> Limit: 10 row(s) (actual time=4657.094..4657.096 rows=9 loops=1)
-> Sort: items.`name`, limit input to 10 row(s) per chunk (actual time=4657.093..4657.094 rows=9 loops=1)
-> Table scan on <temporary> (actual time=0.002..0.003 rows=9 loops=1)
-> Temporary table with deduplication (cost=1141592.47 rows=625722)
(actual time=4657.070..4657.072 rows=9 loops=1)
-> Nested loop inner join (cost=1141592.47 rows=625722) (actual time=0.056..4541.471 rows=85329 loops=1)
-> Filter: (items.`name` like \'%bab%\') (cost=593647.14 rows=625722) (actual time=0.043..4456.394 rows=85329 loops=1)
-> Table scan on items (cost=593647.14 rows=5632061) (actual time=0.037..2864.754 rows=6153656 loops=1)
-> Single-row index lookup on markets using PRIMARY (ID=items.market_id) (cost=0.78 rows=1) (actual time=0.001..0.001 rows=1 loops=85329)
You might get a (small?,) improvement: when you do this:
SELECT items.name,items.ID as itemID,items.market_id as market_id,markets.name as marketname
from items
inner join markets on markets.ID = items.market_id
where markets.ID IN (SELECT items.market_id
FROM marketd
WHERE items.name like '%bab%'
order by items.name ASC
limit 0,10)
order by items.name
EDIT: oops, that's tru you cannot do LIMIT in a subquery....
If you have MySQL 8.0+, you can do:
WITH cte AS (
SELECT items.market_id
FROM marketd
WHERE items.name like '%bab%'
order by items.name ASC
limit 0,10
)
SELECT items.name,items.ID as itemID,items.market_id as market_id,markets.name as marketname
from items
inner join markets on markets.ID = items.market_id
where markets.ID IN ( SELECT market_id
FROM cte )
order by items.name;
also, you might need to add an index on market_id
, if that does not exists yet. With that, the cte will use that index.
This should work with any version of MySQL at least since 5.0:
SELECT items.name,
items.ID as itemID,
items.market_id as market_id,
( SELECT markets.name
FROM markets WHERE markets.ID = items.market_id
) as marketname
FROM items
WHERE items.name like '%bab%'
ORDER BY items.name ASC
LIMIT 10
That should eliminate the GROUP BY
.
Indexes:
items: (name, ID, market_id)
markets: presumably `ID` is the PRIMARY KEY
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.