欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL的一條慢SQL查詢導(dǎo)致整個(gè)網(wǎng)站宕機(jī)的解決方法

 更新時(shí)間:2016年07月16日 15:02:02   投稿:mdxy-dxy  
通常來說,我們看到的慢查詢一般還不致于導(dǎo)致掛站,頂多就是應(yīng)用響應(yīng)變慢不過這個(gè)恰好今天被我撞見了,一個(gè)慢查詢把整個(gè)網(wǎng)站搞掛了

直接切入正題吧:

通常來說,我們看到的慢查詢一般還不致于導(dǎo)致掛站,頂多就是應(yīng)用響應(yīng)變慢
不過這個(gè)恰好今天被我撞見了,一個(gè)慢查詢把整個(gè)網(wǎng)站搞掛了
先看看這個(gè)SQL張撒樣子:

# Query_time: 70.472013 Lock_time: 0.000078 Rows_sent: 7915203 Rows_examined: 15984089 Rows_affected: 0
# Bytes_sent: 1258414478
use js_sku;
SET timestamp=1465850117;
SELECT 
ss_id, ss_sa_id, ss_si_id, ss_av_zid, ss_av_fid, ss_artno,
ss_av_zvalue, ss_av_fvalue, ss_av_zpic, ss_av_fpic, ss_number,
ss_sales, ss_cprice, ss_price, ss_stock, ss_orderid, ss_status,
ss_add_time, ss_lastmodify
FROM js_sgoods_sku
WHERE ss_si_id = 0 AND ss_status > 0
ORDER BY
ss_orderid DESC, ss_av_fid ASC;
這里貼出來的就是 mysql slow log 的信息,查詢時(shí)間用了高達(dá) 70s!!
看到慢查詢我們一般第一反應(yīng)是這個(gè) 語句沒有用到索引? 或者是索引不合理么? 那我們會(huì)去看看執(zhí)行計(jì)劃:

mysql> explain SELECT 
-> ss_id, ss_sa_id, ss_si_id, ss_av_zid, ss_av_fid, ss_artno,
-> ss_av_zvalue, ss_av_fvalue, ss_av_zpic, ss_av_fpic, ss_number,
-> ss_sales, ss_cprice, ss_price, ss_stock, ss_orderid, ss_status,
-> ss_add_time, ss_lastmodify
-> FROM js_sgoods_sku
-> WHERE ss_si_id = 0 AND ss_status > 0
-> ORDER BY
-> ss_orderid DESC, ss_av_fid ASC;
+----+-------------+---------------+------+---------------+----------+---------+-------+---------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+------+---------------+----------+---------+-------+---------+-----------------------------+
| 1 | SIMPLE | js_sgoods_sku | ref | ss_si_id | ss_si_id | 4 | const | 9516091 | Using where; Using filesort |
+----+-------------+---------------+------+---------------+----------+---------+-------+---------+-----------------------------+
1 row in set (0.00 sec)

這個(gè)看起來似乎用到了索引,可是為什么掃描到行還是這么多呢? 那我們就去看看表結(jié)構(gòu)了,期望能從中找到點(diǎn)有價(jià)值的東西:
我們看到如下可用信息:
KEY `ss_si_id` (`ss_si_id`,`ss_av_zid`,`ss_av_fid`) USING BTREE,
`ss_si_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '對(duì)應(yīng)js_sgoods_info.si_id',

我們看到 索引似乎還能比較能夠接受,但是我們看到 這個(gè) ss_si_id 這個(gè)字段實(shí)際上是 goods_info 表的主鍵,也就是說它的離散程度應(yīng)該是很大的,也就是區(qū)分度很大。
其實(shí)到這一步我們基本上可以認(rèn)為 是由于我們這個(gè)表里邊有很多 ss_si_id=0 導(dǎo)致,不過我們可以進(jìn)一步的來證實(shí)我們的猜想:

1. 首先我們可以先確定我們的統(tǒng)計(jì)信息沒有問題
2. 其次我們?cè)賑ount ss_si_id=0 的這個(gè)值有多少數(shù)據(jù),來進(jìn)一步驗(yàn)證我們的猜想。

那么我們先查看以下這個(gè)索引的統(tǒng)計(jì)信息:
xiean@localhost:js_sku 03:27:42>show index from js_sgoods_sku;
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| js_sgoods_sku | 0 | PRIMARY | 1 | ss_id      | A | 18115773 | NULL | NULL | | BTREE | | |
| js_sgoods_sku | 1 | ss_si_id | 1 | ss_si_id   | A  | 1811577  | NULL | NULL | | BTREE | | |
| js_sgoods_sku | 1 | ss_si_id | 2 | ss_av_zid | A | 6038591  | NULL | NULL | | BTREE | | |
| js_sgoods_sku | 1 | ss_si_id | 3 | ss_av_fid | A | 18115773 | NULL | NULL | | BTREE | | |
| js_sgoods_sku | 1 | IDX_001 | 1 | ss_sa_id | A | 3623154   | NULL | NULL | | BTREE | | |
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

那么可以看到以下問題:
我們的ss_si_id 這個(gè)字段并沒有我們表面上看到的 因?yàn)殛P(guān)聯(lián)了某個(gè)表的主鍵,它的Cardinality 值就應(yīng)該接近于 PRIMARY 的值。而是差別比較大的,難道是 索引的統(tǒng)計(jì)信息不準(zhǔn)確? 那我們嘗試重新收集下索引的統(tǒng)計(jì)信息:
xiean@localhost:js_sku 03:27:47>analyze table js_sgoods_sku;
+----------------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+----------------------+---------+----------+----------+
| js_sku.js_sgoods_sku | analyze | status | OK |
+----------------------+---------+----------+----------+

but ,我們?cè)俅尾榭?這些索引的統(tǒng)計(jì)信息:
xiean@localhost:js_sku 03:28:14>show index from js_sgoods_sku;
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| js_sgoods_sku | 0 | PRIMARY | 1 | ss_id      | A | 18621349 | NULL | NULL | | BTREE | | |
| js_sgoods_sku | 1 | ss_si_id | 1 | ss_si_id    | A | 1551779  | NULL | NULL | | BTREE | | |
| js_sgoods_sku | 1 | ss_si_id | 2 | ss_av_zid | A | 6207116   | NULL | NULL | | BTREE | | |
| js_sgoods_sku | 1 | ss_si_id | 3 | ss_av_fid | A | 18621349 | NULL | NULL | | BTREE | | |
| js_sgoods_sku | 1 | IDX_001 | 1 | ss_sa_id | A | 3724269   | NULL | NULL | | BTREE | | |
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

我們可以看到 ss_si_id 的離散程度(Cardinality) 沒有增加反而有向下波動(dòng)的趨勢(shì),因?yàn)檫@個(gè)信息是采集部分頁的來的,而每個(gè)頁上邊數(shù)據(jù)分布是不一樣的,導(dǎo)致我們這個(gè)索引收集的統(tǒng)計(jì)信息就回有所變化。

好吧,到這里我們可以認(rèn)為我們的 統(tǒng)計(jì)信息沒有失效,那么我們就看數(shù)據(jù)的分別情況咯:

+--------------++----------++------------------+
| ss_si_id=0; || count(*) || 7994788/19048617 |
+--------------++----------++------------------+
| 7994788     || 19048617 ||    0.4197           |
+--------------++----------++------------------+

額,不看不知道,一看嚇一跳:我們這個(gè)表里邊 存在有大量的 ss_si_id=0 的情況,占了整個(gè)表數(shù)據(jù)量的 41% !?。?/p>


好吧問題找到了,那么接下來我們需要知道,為什么這個(gè)SQL語句會(huì)導(dǎo)致掛站呢?

我們通過觀看應(yīng)用程序服務(wù)器的監(jiān)控看到一些信息:我們的 goods_service 這個(gè)服務(wù)異常:異常情況如下:

1. cpu 長(zhǎng)期占用100% + 
2. jstatck pid 無法dump 內(nèi)存堆棧信息,必須強(qiáng)制dump -F
3. dump 出來的內(nèi)存信息發(fā)現(xiàn),這個(gè)進(jìn)程里邊所有線程 均處于 BLOCKED 狀態(tài)
4. 通過jstat -gcutil 看到 FGC 相當(dāng)頻繁,10s左右就FGC一次
5. 內(nèi)存占用超過了分配的內(nèi)存

那么最終的原因就是因?yàn)樯线叺穆樵?查詢了大量數(shù)據(jù)(最多有700w行數(shù)據(jù)),導(dǎo)致goods_service 內(nèi)存暴漲,出現(xiàn)服務(wù)無法響應(yīng),進(jìn)一步的惡化就是掛占


OK,知道了為什么會(huì)掛占,那么我們是如何解決這個(gè)問題的呢?
既然我們知道是由于查詢了 ss_si_id=0 導(dǎo)致的,那么我們屏蔽掉這個(gè)SQL不就好了么。屏蔽的辦法可以有多種:
1. 我們程序邏輯判斷一下這類型的 查詢 如果 有查詢 ss_si_id=0 的一律封殺掉
2. 我們改改SQL配置文件,修改SQL語句

我們發(fā)現(xiàn)DB服務(wù)器上存在大量的 這個(gè)慢查詢,而且DB服務(wù)器負(fù)載已經(jīng)從 0.xx 飆升到了 50+ 了,隨之而來的連接數(shù)也飆升的厲害, 如果再不及時(shí)處理,估計(jì)DB服務(wù)器也掛掉了

 

那么我們最終采取以下處理辦法:
1.運(yùn)維配合研發(fā)修改SQL語句 我們?cè)谶@個(gè)WHERE 條件中添加了一個(gè)條件: AND ss_si_id <> 0 ,在MySQL之行計(jì)劃層屏蔽掉此SQL;
2.DBA 開啟kill 掉這個(gè)查詢語句,避免DB服務(wù)器出現(xiàn)down機(jī)的情況,當(dāng)然這個(gè)就用到了我們的 pt-kill 工具,不得不說這個(gè)工具相當(dāng)好用


總結(jié)(經(jīng)驗(yàn)與教訓(xùn)):
1.類似這種查詢 default 值的 SQL ,我們應(yīng)該從源頭上杜絕這類查詢
2.限制查詢結(jié)果集大小,避免因查詢結(jié)果集太大導(dǎo)致服務(wù)死掉

相關(guān)文章

  • SQL實(shí)現(xiàn)LeetCode(177.第N高薪水)

    SQL實(shí)現(xiàn)LeetCode(177.第N高薪水)

    這篇文章主要介紹了SQL實(shí)現(xiàn)LeetCode(177.第N高薪水),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 清理Mysql general_log的方法總結(jié)

    清理Mysql general_log的方法總結(jié)

    在本篇文章里小編給大家分享的是一篇關(guān)于清理Mysql general_log的相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。
    2019-10-10
  • Mysql5升級(jí)到Mysql5.5的方法

    Mysql5升級(jí)到Mysql5.5的方法

    這篇文章主要介紹了Mysql5升級(jí)到Mysql5.5的方法的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • mysqld-nt: Out of memory (Needed 1677720 bytes)解決方法

    mysqld-nt: Out of memory (Needed 1677720 bytes)解決方法

    這篇文章主要介紹了mysqld-nt: Out of memory (Needed 1677720 bytes)解決方法,需要的朋友可以參考下
    2014-12-12
  • MySQL如何優(yōu)雅的刪除大表實(shí)例詳解

    MySQL如何優(yōu)雅的刪除大表實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于MySQL如何優(yōu)雅的刪除大表的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Mysql服務(wù)器的啟動(dòng)與停止(一)

    Mysql服務(wù)器的啟動(dòng)與停止(一)

    Mysql服務(wù)器的啟動(dòng)與停止(一)...
    2006-11-11
  • mysql鎖表和解鎖語句分享

    mysql鎖表和解鎖語句分享

    對(duì)于MySQL來說,有三種鎖的級(jí)別:頁級(jí)、表級(jí)、行級(jí)
    2011-09-09
  • windows2008 64位系統(tǒng)下MySQL 5.7綠色版的安裝教程

    windows2008 64位系統(tǒng)下MySQL 5.7綠色版的安裝教程

    這篇文章主要給大家分享了在windows2008 64位系統(tǒng)下MySQL 5.7綠色版的安裝教程,文中將安裝步驟介紹的非常詳細(xì),相信會(huì)對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • mysql雙游標(biāo)嵌套循環(huán)方式

    mysql雙游標(biāo)嵌套循環(huán)方式

    這篇文章主要介紹了mysql雙游標(biāo)嵌套循環(huán)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • MySQL比較運(yùn)算符使用詳解及注意事項(xiàng)

    MySQL比較運(yùn)算符使用詳解及注意事項(xiàng)

    這篇文章主要給大家介紹了關(guān)于MySQL比較運(yùn)算符使用詳解及注意事項(xiàng)的相關(guān)資料,Mysql可以通過運(yùn)算符來對(duì)表中數(shù)據(jù)進(jìn)行運(yùn)算,比如通過出生日期求年齡等,需要的朋友可以參考下
    2024-01-01

最新評(píng)論