




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯觯袝r(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯?,有時(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引。可以看出,有時(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯觯袝r(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯觯袝r(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯觯袝r(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯?,有時(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯?,有時(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯?,有時(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引。可以看出,有時(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯觯袝r(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯?,有時(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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的性能其實(shí)是挺快的。這樣優(yōu)化之后,sql的執(zhí)行時(shí)間變成了2.5s。性能提升了3倍多,但還是不夠快,還需要做進(jìn)一步優(yōu)化。3第二次優(yōu)化還有一個(gè)notexists可以優(yōu)化一下。如果是小表驅(qū)動(dòng)大表的時(shí)候,使用notexists確實(shí)可以提升性能。但如果是大表驅(qū)動(dòng)小表的時(shí)候,使用notexists可能有點(diǎn)弄巧成拙。這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺(tái)一個(gè)供應(yīng)商的商品并不多。于是,我將notexists改成了notin。sql優(yōu)化如下: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這樣優(yōu)化之后,該sql的執(zhí)行時(shí)間下降到了0.7s。之后,我再用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃。發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引??梢钥闯觯袝r(shí)候sql語(yǔ)句走了4個(gè)索引,性能未必比走了3個(gè)索引好。多張表join的時(shí)候,其中一張表走了全表掃描,說(shuō)不定整個(gè)SQL語(yǔ)句的性能會(huì)更好,我們一定要多測(cè)試。1案發(fā)現(xiàn)場(chǎng)前幾天,我收到了一封報(bào)警郵件,提示有一條慢查詢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的含義是統(tǒng)計(jì)id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。這條SQL的耗時(shí)竟然達(dá)標(biāo)了8s,必須要做優(yōu)化了。我首先使用explain關(guān)鍵字查詢?cè)揝QL的執(zhí)行計(jì)劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。也就是說(shuō),這4張表都走了索引。不是簡(jiǎn)單的增加索引就能解決的事情。那么,接下來(lái)該如何優(yōu)化呢?2第一次優(yōu)化這條SQL語(yǔ)句,其中兩個(gè)exists關(guān)鍵字引起了我的注意。一個(gè)exists是為了查詢存在某些滿足條件的商品,另一個(gè)notexists是為了查詢出不存在某些商品。這個(gè)SQL是另外一位已離職的同事寫的。不清楚spu表和sku表為什么不用join,而用了exists。我猜測(cè)可能是為了只返回spu表的數(shù)據(jù),而做的一種處理。如果join了sku表,則可能會(huì)查出重復(fù)的數(shù)據(jù),需要做去重處理。從目前看,這種寫性能有瓶頸。因此,我做出了第一次優(yōu)化。使用join
+
groupby組合,將sql優(yōu)化如下: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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 農(nóng)業(yè)訂單收購(gòu)合同范本
- 茶葉采購(gòu)與銷售合同樣本
- 無(wú)子女離婚法律合同文本
- 正式勞動(dòng)合同書范本合同
- 家居用品采購(gòu)及安裝合同范本
- 8安全記心上-119的警示(第3課時(shí))(教學(xué)設(shè)計(jì))2023-2024學(xué)年統(tǒng)編版道德與法治三年級(jí)上冊(cè)
- 10古詩(shī)三首《石灰吟》《竹石》教學(xué)設(shè)計(jì)-2023-2024學(xué)年六年級(jí)語(yǔ)文下冊(cè)統(tǒng)編版
- 人事管理合同樣本大全
- 6《景陽(yáng)岡》教學(xué)設(shè)計(jì)-2023-2024學(xué)年語(yǔ)文五年級(jí)下冊(cè)統(tǒng)編版
- 個(gè)人保證貸款合同范本
- GB 9706.202-2021醫(yī)用電氣設(shè)備第2-2部分:高頻手術(shù)設(shè)備及高頻附件的基本安全和基本性能專用要求
- 馬工程教材《公共財(cái)政概論》PPT-緒論
- GB/T 26752-2020聚丙烯腈基碳纖維
- 民間曲藝戲曲課件
- 基于項(xiàng)目式學(xué)習(xí)的課程構(gòu)建與實(shí)施
- 各級(jí)醫(yī)療機(jī)構(gòu)醫(yī)院醫(yī)用高壓氧治療技術(shù)管理規(guī)范
- 監(jiān)理人員安全生產(chǎn)職責(zé)目標(biāo)考核與獎(jiǎng)罰辦法
- AUMA澳瑪執(zhí)行器內(nèi)部培訓(xùn)課件
- 加強(qiáng)營(yíng)房管理的對(duì)策
- M系列警報(bào)明細(xì)表復(fù)習(xí)課程
- 施工隊(duì)結(jié)算單
評(píng)論
0/150
提交評(píng)論