国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫(kù)技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫(kù) - Mysql - 通過(guò)MySQL優(yōu)化Discuz!的熱帖翻頁(yè)的技巧

通過(guò)MySQL優(yōu)化Discuz!的熱帖翻頁(yè)的技巧

2020-05-05 16:47葉金榮 Mysql

這篇文章主要介紹了通過(guò)MySQL優(yōu)化Discuz!的熱帖翻頁(yè)的技巧,包括更新索引來(lái)降低服務(wù)器負(fù)載等方面,需要的朋友可以參考下

寫(xiě)在前面:discuz!作為首屈一指的社區(qū)系統(tǒng),為廣大站長(zhǎng)提供了一站式網(wǎng)站解決方案,而且是開(kāi)源的(雖然部分代碼是加密的),它為這個(gè)垂直領(lǐng)域的行業(yè)發(fā)展作出了巨大貢獻(xiàn)。盡管如此,discuz!系統(tǒng)源碼中,還是或多或少有些坑。其中最著名的就是默認(rèn)采用MyISAM引擎,以及基于MyISAM引擎的搶樓功能,session表采用memory引擎等,可以參考后面幾篇?dú)v史文章。本次我們要說(shuō)說(shuō)discuz!在應(yīng)對(duì)熱們帖子翻頁(yè)邏輯功能中的另一個(gè)問(wèn)題。

在我們的環(huán)境中,使用的是 MySQL-5.6.6 版本。

在查看帖子并翻頁(yè)過(guò)程中,會(huì)產(chǎn)生類(lèi)似下面這樣的SQL:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> desc SELECT * FROM pre_forum_post WHERE
 tid=8201301 AND `invisible` IN('0','-2') ORDER BY dateline DESC LIMIT 15\G
 *************************** 1. row ***************************
 id: 1
 select_type: SIMPLE
 table: pre_forum_post
 type: ref
 possible_keys: tid,displayorder,first
 key: displayorder
 key_len: 3
 ref: const
 rows: 593371
 Extra: Using index condition; Using where; Using filesort

這個(gè)SQL執(zhí)行的代價(jià)是:

-- 根據(jù)索引訪問(wèn)行記錄次數(shù),總體而言算是比較好的狀態(tài)

?
1
| Handler_read_key   | 16  |

-- 根據(jù)索引順序訪問(wèn)下一行記錄的次數(shù),通常是因?yàn)楦鶕?jù)索引的范圍掃描,或者全索引掃描,總體而言也算是比較好的狀態(tài)

?
1
| Handler_read_next   | 329881 |

-- 按照一定順序讀取行記錄的總次數(shù)。如果需要對(duì)結(jié)果進(jìn)行排序,該值通常會(huì)比較大。當(dāng)發(fā)生全表掃描或者多表join無(wú)法使用索引時(shí),該值也會(huì)比較大

?
1
| Handler_read_rnd   | 15  |

而當(dāng)遇到熱帖需要往后翻很多頁(yè)時(shí),例如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> desc SELECT * FROM pre_forum_post WHERE
 tid=8201301 AND `invisible` IN('0','-2') ORDER BY dateline LIMIT 129860, 15\G
 *************************** 1. row ***************************
 id: 1
 select_type: SIMPLE
 table: pre_forum_post
 type: ref
 possible_keys: displayorder
 key: displayorder
 key_len: 3
 ref: const
 rows: 593371
 Extra: Using where; Using filesort

這個(gè)SQL執(zhí)行的代價(jià)則變成了(可以看到Handler_read_key、Handler_read_rnd大了很多):

| Handler_read_key           | 129876 | -- 因?yàn)榍懊嫘枰^(guò)很多行記錄
| Handler_read_next          | 329881 | -- 同上
| Handler_read_rnd           | 129875 | -- 因?yàn)樾枰葘?duì)很大一個(gè)結(jié)果集進(jìn)行排序

可見(jiàn),遇到熱帖時(shí),這個(gè)SQL的代價(jià)會(huì)非常高。如果該熱帖被大量的訪問(wèn)歷史回復(fù),或者被搜素引擎一直反復(fù)請(qǐng)求并且歷史回復(fù)頁(yè)時(shí),很容易把數(shù)據(jù)庫(kù)服務(wù)器直接壓垮。

小結(jié):這個(gè)SQL不能利用 `displayorder` 索引排序的原因是,索引的第二個(gè)列 `invisible` 采用范圍查詢(xún)(RANGE),導(dǎo)致沒(méi)辦法繼續(xù)利用聯(lián)合索引完成對(duì) `dateline` 字段的排序需求(而如果是 WHERE tid =? AND invisible IN(?, ?) AND dateline =? 這種情況下是完全可以用到整個(gè)聯(lián)合索引的,注意下二者的區(qū)別)。

知道了這個(gè)原因,相應(yīng)的優(yōu)化解決辦法也就清晰了:
創(chuàng)建一個(gè)新的索引 idx_tid_dateline,它只包括 tid、dateline 兩個(gè)列即可(根據(jù)其他索引的統(tǒng)計(jì)信息,item_type 和 item_id 的基數(shù)太低,所以沒(méi)包含在聯(lián)合索引中。當(dāng)然了,也可以考慮一并加上)。

我們?cè)賮?lái)看下采用新的索引后的執(zhí)行計(jì)劃:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> desc SELECT * FROM pre_forum_post WHERE
 tid=8201301 AND `invisible` IN('0','-2') ORDER BY dateline LIMIT 15\G
 *************************** 1. row ***************************
 id: 1
 select_type: SIMPLE
 table: pre_forum_post
 type: ref
 possible_keys: tid,displayorder,first,idx_tid_dateline
 key: idx_tid_dateline
 key_len: 3
 ref: const
 rows: 703892
 Extra: Using where

可以看到,之前存在的 Using filesort 消失了,可以通過(guò)索引直接完成排序了。

不過(guò),如果該熱帖翻到較舊的歷史回復(fù)時(shí),相應(yīng)的SQL還是不能使用新的索引:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> desc SELECT * FROM pre_forum_post WHERE
 tid=8201301 AND `invisible` IN('0','-2') ORDER BY dateline LIMIT 129860,15\G
 *************************** 1. row ***************************
 id: 1
 select_type: SIMPLE
 table: pre_forum_post
 type: ref
 possible_keys: tid,displayorder,first,idx_tid_dateline
 key: displayorder
 key_len: 3
 ref: const
 rows: 593371
 Extra: Using where; Using filesort

對(duì)比下如果建議優(yōu)化器使用新索引的話(huà),其執(zhí)行計(jì)劃是怎樣的:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> desc SELECT * FROM pre_forum_post use index(idx_tid_dateline) WHERE
 tid=8201301 AND `invisible` IN('0','-2') ORDER BY dateline LIMIT 129860,15\G
 *************************** 1. row ***************************
 id: 1
 select_type: SIMPLE
 table: pre_forum_post
 type: ref
 possible_keys: idx_tid_dateline
 key: idx_tid_dateline
 key_len: 3
 ref: const
 rows: 703892
 Extra: Using where

可以看到,因?yàn)椴樵?xún)優(yōu)化器認(rèn)為后者需要掃描的行數(shù)遠(yuǎn)比前者多了11萬(wàn)多,因此認(rèn)為前者效率更高。

事實(shí)上,在這個(gè)例子里,排序的代價(jià)更高,因此我們要優(yōu)先消除排序,所以應(yīng)該強(qiáng)制使用新的索引,也就是采用后面的執(zhí)行計(jì)劃,在相應(yīng)的程序中指定索引。

最后,我們來(lái)看下熱帖翻到很老的歷史回復(fù)時(shí),兩個(gè)執(zhí)行計(jì)劃分別的profiling統(tǒng)計(jì)信息對(duì)比:

1、采用舊索引(displayorder):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> SELECT * FROM pre_forum_post WHERE
 tid=8201301 AND `invisible` IN('0','-2') ORDER BY dateline LIMIT 129860,15;
 
#查看profiling結(jié)果
 | starting    | 0.020203 |
 | checking permissions | 0.000026 |
 | Opening tables  | 0.000036 |
 | init     | 0.000099 |
 | System lock   | 0.000092 |
 | optimizing   | 0.000038 |
 | statistics   | 0.000123 |
 | preparing   | 0.000043 |
 | Sorting result  | 0.000025 |
 | executing   | 0.000023 |
 | Sending data   | 0.000045 |
 | Creating sort index | 0.941434 |
 | end     | 0.000077 |
 | query end   | 0.000044 |
 | closing tables  | 0.000038 |
 | freeing items  | 0.000056 |
 | cleaning up   | 0.000040 |

2、如果是采用新索引(idx_tid_dateline):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mysql> SELECT * FROM pre_forum_post use index(idx_tid_dateline) WHERE
 tid=8201301 AND `invisible` IN('0','-2') ORDER BY dateline LIMIT 129860,15;
 
#對(duì)比查看profiling結(jié)果
 | starting    | 0.000151 |
 | checking permissions | 0.000033 |
 | Opening tables  | 0.000040 |
 | init     | 0.000105 |
 | System lock   | 0.000044 |
 | optimizing   | 0.000038 |
 | statistics   | 0.000188 |
 | preparing   | 0.000044 |
 | Sorting result  | 0.000024 |
 | executing   | 0.000023 |
 | Sending data   | 0.917035 |
 | end     | 0.000074 |
 | query end   | 0.000030 |
 | closing tables  | 0.000036 |
 | freeing items  | 0.000049 |
 | cleaning up   | 0.000032 |

可以看到,效率有了一定提高,不過(guò)不是很明顯,因?yàn)榇_實(shí)需要掃描的數(shù)據(jù)量更大,所以 Sending data 階段耗時(shí)更多。

這時(shí)候,我們可以再參考之前的一個(gè)優(yōu)化方案:[MySQL優(yōu)化案例]系列 — 分頁(yè)優(yōu)化

然后可以將這個(gè)SQL改寫(xiě)成下面這樣:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
mysql> EXPLAIN SELECT * FROM pre_forum_post t1 INNER JOIN (
 SELECT id FROM pre_forum_post use index(idx_tid_dateline) WHERE
 tid=8201301 AND `invisible` IN('0','-2') ORDER BY
 dateline LIMIT 129860,15) t2
 USING (id)\G
 *************************** 1. row ***************************
 id: 1
 select_type: PRIMARY
 table:
 type: ALL
 possible_keys: NULL
 key: NULL
 key_len: NULL
 ref: NULL
 rows: 129875
 Extra: NULL
 *************************** 2. row ***************************
 id: 1
 select_type: PRIMARY
 table: t1
 type: eq_ref
 possible_keys: PRIMARY
 key: PRIMARY
 key_len: 4
 ref: t2.id
 rows: 1
 Extra: NULL
 *************************** 3. row ***************************
 id: 2
 select_type: DERIVED
 table: pre_forum_post
 type: ref
 possible_keys: idx_tid_dateline
 key: idx_tid_dateline
 key_len: 3
 ref: const
 rows: 703892
 Extra: Using where

再看下這個(gè)SQL的 profiling 統(tǒng)計(jì)信息:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| starting    | 0.000209 |
| checking permissions | 0.000026 |
| checking permissions | 0.000026 |
| Opening tables  | 0.000101 |
| init     | 0.000062 |
| System lock   | 0.000049 |
| optimizing   | 0.000025 |
| optimizing   | 0.000037 |
| statistics   | 0.000106 |
| preparing   | 0.000059 |
| Sorting result  | 0.000039 |
| statistics   | 0.000048 |
| preparing   | 0.000032 |
| executing   | 0.000036 |
| Sending data   | 0.000045 |
| executing   | 0.000023 |
| Sending data   | 0.225356 |
| end     | 0.000067 |
| query end   | 0.000028 |
| closing tables  | 0.000023 |
| removing tmp table | 0.000029 |
| closing tables  | 0.000044 |
| freeing items  | 0.000048 |
| cleaning up   | 0.000037 |

可以看到,效率提升了1倍以上,還是挺不錯(cuò)的。

最后說(shuō)明下,這個(gè)問(wèn)題只會(huì)在熱帖翻頁(yè)時(shí)才會(huì)出現(xiàn),一般只有1,2頁(yè)回復(fù)的帖子如果還采用原來(lái)的執(zhí)行計(jì)劃,也沒(méi)什么問(wèn)題。

因此,建議discuz!官方修改或增加下新索引,并且在代碼中判斷是否熱帖翻頁(yè),是的話(huà),就強(qiáng)制使用新的索引,以避免性能問(wèn)題。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲国产精品视频 | 草久在线视频 | 久久成人国产 | 天天av网 | 91精品国产一区二区 | 国产福利视频在线观看 | 亚洲国产精品久久久 | 99精品欧美一区二区三区综合在线 | 网站黄色在线观看免费 | av不卡电影在线观看 | 精品久久精品 | 欧美wwwsss9999 | av在线天堂网| 日韩午夜 | 国内自拍视频在线观看 | 国产精品久久国产精品 | 国产精品久久久久久久久久久久久 | 久久国产精品一区二区 | 欧美成人免费在线视频 | 国产在线精品视频 | 成年人毛片视频 | 91中文字幕在线 | 免费观看a级毛片在线播放 成人片免费看 | 久久中文字幕一区 | 91丝袜 | 日本激情视频一区二区三区 | 欧美日韩在线观看一区二区 | 久久久亚洲国产天美传媒修理工 | 久草久草久草 | 国产成人av在线播放 | 精品一二三区 | 免费在线成人网 | 欧美精品综合 | 成人综合电影网 | 日韩欧美三区 | 在线中文视频 | 亚洲一区自拍 | 亚洲综合在线视频 | 欧美午夜一区二区福利视频 | 日日干夜夜操 | 欧美一级二级视频 |