mysql 为什么使用文本id的id查询比使用子查询的查询快得多?

gab6jxml  于 2023-02-03  发布在  Mysql
关注(0)|答案(1)|浏览(174)

我构建了一个查询,对超过20万条记录进行排序,并在7秒内返回28条记录。

select idcustomer
from sale s 
inner join customer c on c.idCustomer = s.fkCustomer
WHERE s.dateSale between '1700-01-01' and '2022-01-26'
    and c.fkCompany = 'b92c5957-9275-4fa5-9970-1a41eb524328'

此查询正在使用以下索引:

create index customer_fkCompanyx on dactai.customer(fkCompany, idcustomer);

我还想查询列c.firstnamec.lastname,但是当我将它们添加到上面的查询中时,查询需要40秒才能返回。我读到这可能是因为RID和数据库必须查询实际的表而不是索引来获取额外的列。然后我尝试将这两列添加到索引中,创建一个“覆盖索引”但是列太大并且外推索引的最大大小。
然后我尝试了一种不同的方法,我尝试将此查询添加为子查询,如下所示:

select firstname from customer where idcustomer in (
    select idcustomer
    from sale s 
    inner join customer c on c.idCustomer = s.fkCustomer
    WHERE s.dateSale between '1700-01-01' and '2022-01-26'
        and c.fkCompany = 'b92c5957-9275-4fa5-9970-1a41eb524328'
)

这种方法需要20秒,所以比单独的子查询多13秒。奇怪的是,包含所有28个文本id的外部查询会立即返回。
为什么花费0秒的外部查询加上花费7秒的子查询会导致花费20秒的查询,而具有相同的28个id但文字的外部查询花费0秒?另外,是否有方法将名和姓添加到原始查询而不花费40秒?

mgdq6dx1

mgdq6dx11#

c:  INDEX(fkCompany, idCustomer)
s:  INDEX(dateSale, fkCustomer)
s:  INDEX(fkCustomer, dateSale)

还有试试

select  c.firstname
    from  customer AS c
    JOIN  sale AS s  ON c.idCustomer = s.fkCustomer
    WHERE  s.dateSale between '1700-01-01' AND '2022-01-26'
      and  c.fkCompany = 'b92c5957-9275-4fa5-9970-1a41eb524328'

并将第一个索引建议更改为

c:  INDEX(fkCompany, idCustomer,  firstname, lastname)

为了进一步讨论,请为每个表提供SHOW CREATE TABLE

相关问题