宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見(jiàn)問(wèn)題
產(chǎn)品動(dòng)態(tài)
精選推薦

MySQL 查詢(xún)優(yōu)化器與 SQL 調(diào)試

管理 管理 編輯 刪除

1、MySQL 查詢(xún)優(yōu)化器與 SQL 調(diào)試 (一)

要想寫(xiě)出更好的 SQL,一些基礎(chǔ)概念和 SQL 調(diào)試是必不可少的。下面我們來(lái)看下查詢(xún)優(yōu)化器給我們做了哪些優(yōu)化,執(zhí)行器真正執(zhí)行的 SQL 語(yǔ)句是什么。

首先了解一些基礎(chǔ)的概念。

1.1、MySQL 客戶(hù)端與服務(wù)端的通信協(xié)議

MySQL 客戶(hù)端與服務(wù)端的通信協(xié)議為 “半雙工”,也就是在任何一個(gè)時(shí)刻,只能由服務(wù)端發(fā)送數(shù)據(jù)到客戶(hù)端,或者反之,兩個(gè)動(dòng)作不能同時(shí)發(fā)生。這就導(dǎo)致了沒(méi)法進(jìn)行流量控制,一旦一端開(kāi)始發(fā)送消息,另外一端要完整接收消息才能響應(yīng)對(duì)方。如果發(fā)送的數(shù)據(jù)太長(zhǎng),MySQL 會(huì)拒絕接收更多的數(shù)據(jù)直接拋出異常,這時(shí)候可以通過(guò)設(shè)置 ‘max_allowed_packet’ 來(lái)調(diào)節(jié)可以發(fā)送的數(shù)據(jù)量大小,單位是 Byte。

而 MySQL 客戶(hù)端接收服務(wù)端發(fā)送的數(shù)據(jù)可能由多個(gè)數(shù)據(jù)包組成。在接收數(shù)據(jù)的過(guò)程看起來(lái)像是客戶(hù)端主動(dòng)去拉數(shù)據(jù),但實(shí)際上是服務(wù)端主動(dòng)去推送數(shù)據(jù)到客戶(hù)端,客戶(hù)端無(wú)法主動(dòng)的讓服務(wù)端停止下來(lái),只有當(dāng)所有數(shù)據(jù)發(fā)送給客戶(hù)端后才會(huì)釋放這條查詢(xún)所占用的資源。

1.2、查詢(xún) MySQL 服務(wù)端所有連接線(xiàn)程狀態(tài)

對(duì)于客戶(hù)端和服務(wù)端的通信都會(huì)通過(guò)線(xiàn)程去操作,而每個(gè)線(xiàn)程都會(huì)有屬于它的狀態(tài),我們可以使用 show processlist 去查看相應(yīng)線(xiàn)程的連接信息。

  • Id

連接標(biāo)識(shí)符。這個(gè)值來(lái)自于 INFORMATION_SCHEMA 數(shù)據(jù)庫(kù)的 PROCESSLIST 表的 ID 值,通過(guò) CONNECTION_ID() 函數(shù)返回。

  • User

連接的用戶(hù)(用戶(hù)名)。system user 的值是指服務(wù)器生成的非客戶(hù)端線(xiàn)程,用于處理內(nèi)部的任務(wù)。比如:延遲行處理程序線(xiàn)程或副本主機(jī)上使用的 I/O 或 SQL 線(xiàn)程。對(duì)于 system user, Host列中未指定主機(jī)。unauthenticated user 指的是與客戶(hù)端已經(jīng)連接但是還未身份認(rèn)證的線(xiàn)程。event_scheduler指的是監(jiān)控調(diào)度事件的線(xiàn)程。

  • Host

主機(jī)名(連接地址)(system user 沒(méi)有主機(jī)的除外)。以 TCP/IP 連接的主機(jī)名通過(guò)host_name:client_port格式去顯示更容易知道客戶(hù)端正在做什么。

  • db

線(xiàn)程默認(rèn)的數(shù)據(jù)庫(kù),沒(méi)有選擇則顯示 NULL。

  • Command

客戶(hù)端執(zhí)行命令的類(lèi)型,如果是 Sleep 則表示是空閑狀態(tài)。

更多參數(shù)值請(qǐng)查閱官方文檔:https://dev.mysql.com/doc/refman/8.0/en/thread-commands.html

  • Time

線(xiàn)程處于當(dāng)前狀態(tài)的時(shí)間(以秒為單位)。對(duì)于 replica 線(xiàn)程,該值是最后一次同步事件到 replica host 之間的毫秒數(shù)。

  • State

動(dòng)作、事件或者狀態(tài)。大多數(shù)狀態(tài)流轉(zhuǎn)的速度是非??斓模绻€(xiàn)程一直停留在一個(gè)狀態(tài),那么應(yīng)該檢查一下當(dāng)前狀態(tài)是否出現(xiàn)什么問(wèn)題了。

更多狀態(tài)值請(qǐng)查詢(xún)官方文檔:https://dev.mysql.com/doc/refman/8.0/en/general-thread-states.html

  • Info

線(xiàn)程正在執(zhí)行的語(yǔ)句,如果沒(méi)有執(zhí)行任何語(yǔ)句的話(huà)就是 NULL。

show processlist 只能查看 info 當(dāng)中的前 100 個(gè)字符,如果想要查看完整的字符,請(qǐng)使用 show full processlist。

1.4、查詢(xún)優(yōu)化器

MySQL 使用基于成本的優(yōu)化器,它將嘗試預(yù)測(cè)一個(gè)查詢(xún)使用某種執(zhí)行計(jì)劃時(shí)的成本,并選擇其中成本最小的一個(gè)。

如何查詢(xún) SQL 的執(zhí)行成本呢?

我們可以使用 explain + FORMAT=JSON 的方式查看具體的執(zhí)行計(jì)劃:

explain FORMAT=JSON select * from alarm_record


{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "0.35"
    },
    "table": {
      "table_name": "alarm_record",
      "access_type": "ALL",
      "rows_examined_per_scan": 1,
      "rows_produced_per_join": 1,
      "filtered": "100.00",
      "cost_info": {
        "read_cost": "0.25",
        "eval_cost": "0.10",
        "prefix_cost": "0.35",
        "data_read_per_join": "2K"
      },
      "used_columns": [
        "id",
        "product_id",
		"..."
      ]
    }
  }
}

其中 query_cost 就是總的查詢(xún)成本,大概要讀 0.35 個(gè)數(shù)據(jù)頁(yè),而數(shù)據(jù)頁(yè)的默認(rèn)大小是 16 KB。

而導(dǎo)致 MySQL 選擇錯(cuò)誤的執(zhí)行計(jì)劃可能有以下原因(不一樣全):

  • 統(tǒng)計(jì)信息不準(zhǔn)確。

MySQL 依賴(lài)存儲(chǔ)引擎提供的統(tǒng)計(jì)信息來(lái)估計(jì)成本,但是有的引擎給出的統(tǒng)計(jì)成本不一定準(zhǔn)確,可能誤差會(huì)比較大。

  • 執(zhí)行計(jì)劃中的成本不等同于實(shí)際的執(zhí)行成本。
  • MySQL 中的最優(yōu)可能不是我們想象中的速度最快。

因?yàn)?MySQL 只是基于其成本模型選擇的最優(yōu)執(zhí)行計(jì)劃,有時(shí)候選擇的不一定是最快的。

  • MySQL 從不考慮其他并發(fā)執(zhí)行的查詢(xún),這可能會(huì)影響到當(dāng)前的查詢(xún)速度。
  • MySQL 也不是任何時(shí)候都是基于成本的優(yōu)化。
  • MySQL 不會(huì)考慮不受其控制的操作成本。
1.4.1、查詢(xún)優(yōu)化器做了哪些優(yōu)化

有以下部分優(yōu)化內(nèi)容:

  • 重新定義關(guān)聯(lián)表順序

MySQL 會(huì)根據(jù)相關(guān)的嵌套循環(huán)算法找到掃描行數(shù)更少的表去重新定義關(guān)聯(lián)順序。但是有時(shí)候優(yōu)化器給出的不是最佳的關(guān)聯(lián)順序,如果有超過(guò) n 個(gè)表的關(guān)聯(lián),優(yōu)化器需要檢查 n 的階乘種關(guān)聯(lián)順序,當(dāng)這個(gè)變得非常大的時(shí)候,優(yōu)化器不可能去檢查每一種的關(guān)聯(lián)成本,這時(shí)候優(yōu)化器會(huì)選擇 “貪婪” 搜索的方式查找 “最優(yōu)” 的關(guān)聯(lián)順序。

當(dāng)關(guān)聯(lián)的表超過(guò) optimizer_search_depth 配置的時(shí)候,就會(huì)選擇 “貪婪” 的搜索模式了(show VARIABLES like 'optimizer_search_depth')。

  • 將外連接轉(zhuǎn)換成內(nèi)連接
  • 使用登記變換規(guī)則

MySQL 會(huì)合并比較、移除一些恒成立和恒不成立的判斷。

  • 優(yōu)化 count()、min()和max()

想要找到某一列的最小值,只需要查詢(xún)對(duì)應(yīng) B-Tree 索引的最左端的記錄,優(yōu)化器在優(yōu)化的時(shí)候會(huì)將這個(gè)表達(dá)式當(dāng)成一個(gè)常數(shù)對(duì)待。如果 MySQL 使用了這種類(lèi)型的優(yōu)化,在 explain 中可以看到 “select tables optimized away”。

  • 預(yù)估并轉(zhuǎn)化為常數(shù)表達(dá)式
  • 覆蓋索引掃描
  • 子查詢(xún)優(yōu)化

MySQL 某些情況可以將子查詢(xún)轉(zhuǎn)換成一種效率更高的形式,從而減少多個(gè)查詢(xún)多次對(duì)數(shù)據(jù)進(jìn)行訪(fǎng)問(wèn)。

  • 提前終止查詢(xún)

在發(fā)現(xiàn)已經(jīng)滿(mǎn)足查詢(xún)需求的時(shí)候,MySQL 總能立即終止查詢(xún)。

  • 等值傳播
  • 列表 in() 的比較

MySQL 會(huì)將 in 列表中的數(shù)據(jù)先進(jìn)行排序,然后通過(guò)二分查找來(lái)確定列表中的值是否滿(mǎn)足條件,對(duì)于 in 列表中有大量取值的時(shí)候,MySQL 的處理速度會(huì)更快。

參考文檔

  • 高性能 MySQL 第三版
  • MySQL 8.0 官方文檔
請(qǐng)登錄后查看

CRMEB-慕白寒窗雪 最后編輯于2023-03-03 15:30:09

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認(rèn)正序 回復(fù)倒序 點(diǎn)贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}}
沙發(fā) 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暫無(wú)簡(jiǎn)介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
2735
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
{{item.label}} 加精
{{item.label}} {{item.label}} 板塊推薦 常見(jiàn)問(wèn)題 產(chǎn)品動(dòng)態(tài) 精選推薦 首頁(yè)頭條 首頁(yè)動(dòng)態(tài) 首頁(yè)推薦
取 消 確 定
回復(fù)
回復(fù)
問(wèn)題:
問(wèn)題自動(dòng)獲取的帖子內(nèi)容,不準(zhǔn)確時(shí)需要手動(dòng)修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當(dāng)前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請(qǐng)輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認(rèn)打賞

微信登錄/注冊(cè)

切換手機(jī)號(hào)登錄

{{ bind_phone ? '綁定手機(jī)' : '手機(jī)登錄'}}

{{codeText}}
切換微信登錄/注冊(cè)
暫不綁定
CRMEB客服

CRMEB咨詢(xún)熱線(xiàn) 咨詢(xún)熱線(xiàn)

400-8888-794

微信掃碼咨詢(xún)

CRMEB開(kāi)源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服