简体   繁体   English

如何使用 group by 和 order by 使查询更快

[英]How to make query faster with group by and order by

I have large table with 615 million records in items and 10 thousand in markets我有一张大表,里面有 6.15 亿条记录和 1 万条市场记录

the below query takes 5+ seconds to execute下面的查询需要 5+ 秒才能执行

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....编辑:哎呀,这是真的,你不能在子查询中做 LIMIT ......

If you have MySQL 8.0+, you can do:如果你有 MySQL 8.0+,你可以这样做:

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.此外,您可能需要在market_id上添加一个索引(如果该索引尚不存在)。 With that, the cte will use that index.这样,cte 将使用该索引。

This should work with any version of MySQL at least since 5.0:这应该适用于任何版本的 MySQL 至少从 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 .那应该消除GROUP BY

Indexes:索引:

items:  (name, ID, market_id)
markets:  presumably `ID` is the PRIMARY KEY

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM