繁体   English   中英

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

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

我有一张大表,里面有 6.15 亿条记录和 1 万条市场记录

下面的查询需要 5+ 秒才能执行

我怎样才能让它更快。 ?

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

解释

在此处输入图像描述

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

你可能会得到一个(小的?)改进:当你这样做时:

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

编辑:哎呀,这是真的,你不能在子查询中做 LIMIT ......

如果你有 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;

此外,您可能需要在market_id上添加一个索引(如果该索引尚不存在)。 这样,cte 将使用该索引。

这应该适用于任何版本的 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

那应该消除GROUP BY

索引:

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