一次显著的性能优化_第1页
一次显著的性能优化_第2页
一次显著的性能优化_第3页
一次显著的性能优化_第4页
一次显著的性能优化_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论