版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
not
exists
(
select
*
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此groupby的性能其实是挺快的。这样优化之后,sql的执行时间变成了2.5s。性能提升了3倍多,但还是不够快,还需要做进一步优化。3第二次优化还有一个notexists可以优化一下。如果是小表驱动大表的时候,使用notexists确实可以提升性能。但如果是大表驱动小表的时候,使用notexists可能有点弄巧成拙。这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。于是,我将notexists改成了notin。sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.status=1
and
s3.id
not
IN
(
select
s4.mall_sku_id
from
supplier_sku
s4
where
s4.mall_sku_id=s3.id
and
s4.supplier_id=...
)
group
by
s2.spu_id
)
a这样优化之后,该sql的执行时间下降到了0.7s。之后,我再用explain关键字查询该SQL的执行计划。发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。1案发现场前几天,我收到了一封报警邮件,提示有一条慢查询SQL。我打开邮件查看了详情,那条SQL大概是这样的:SELECT
count(*)
FROM
spu
s1
WHERE
EXISTS
(
SELECT
*
FROM
sku
s2
INNER
JOIN
mall_sku
s3
ON
s3.sku_id
=
s2.id
WHERE
s2.spu_id
=
s1.id
AND
s2.status
=
1
AND
NOT
EXISTS
(
SELECT
*
FROM
supplier_sku
s4
WHERE
s4.mall_sku_id
=
s3.id
AND
s4.supplier_id
=
123456789
AND
s4.status
=
1
)
)这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。这条SQL的耗时竟然达标了8s,必须要做优化了。我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。也就是说,这4张表都走了索引。不是简单的增加索引就能解决的事情。那么,接下来该如何优化呢?2第一次优化这条SQL语句,其中两个exists关键字引起了我的注意。一个exists是为了查询存在某些满足条件的商品,另一个notexists是为了查询出不存在某些商品。这个SQL是另外一位已离职的同事写的。不清楚spu表和sku表为什么不用join,而用了exists。我猜测可能是为了只返回spu表的数据,而做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。从目前看,这种写性能有瓶颈。因此,我做出了第一次优化。使用join
+
groupby组合,将sql优化如下:SELECT
count(*)
FROM
(
select
s2.spu_id
from
spu
s1
inner
join
from
sku
s2
inner
join
mall_sku
s3
on
s3.sku_id=s2.id
where
s2.spu_id=s1.id
ans
s2.st
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 运动健身的训练安排计划
- 家政行业话务员工作总结
- 中班主题有趣的石头
- 幼儿园大班上学期科学教案有关《磁力组合》课件
- 美容院前台工作感受
- 生活美学创意课程设计
- 现代理论课程设计
- 2024年新型建筑工程原材料采购标准协议模板版
- 我的纸片人爸爸读后感
- 捐赠活动领导讲话稿
- 场地硬化合同范文
- 智力残疾送教上门教案
- 2024年上海市中考数学试卷真题(含答案)
- 刑事诉讼法综合实训报告
- 部编版五年级上册语文第七单元《-即景》作文500字【9篇】
- 2024年广东能源集团天然气有限公司招聘笔试参考题库附带答案详解
- 垃圾运输清运合同
- 基础工程-赵明华-第二章
- 肾病科主任述职报告
- 2023-2024全国初中物理竞赛试题第11讲压强(解析版)
- 扩大高水平对外开放课件
评论
0/150
提交评论