
在 MySQL 數(shù)據(jù)庫(kù)的查詢優(yōu)化中,執(zhí)行計(jì)劃(EXPLAIN
輸出)是開發(fā)者和 DBA 分析查詢性能的核心工具。其中,rows
列作為執(zhí)行計(jì)劃的關(guān)鍵指標(biāo),代表優(yōu)化器估計(jì)的當(dāng)前操作需要掃描的行數(shù)。這個(gè)數(shù)值直接反映了查詢的效率 —— 行數(shù)越少,查詢通常越高效。但很多人對(duì)這個(gè)數(shù)值的計(jì)算邏輯感到困惑:它究竟是怎么來的?為何有時(shí)會(huì)與實(shí)際掃描行數(shù)相差較大?本文將從原理到實(shí)踐,全面解析 MySQL 執(zhí)行計(jì)劃中rows
的計(jì)算邏輯。
在深入計(jì)算邏輯前,需先明確rows
的本質(zhì):它是 MySQL 優(yōu)化器基于統(tǒng)計(jì)信息和數(shù)據(jù)分布規(guī)律,對(duì)查詢執(zhí)行過程中需要訪問的行數(shù)的 “預(yù)測(cè)值”,而非實(shí)際執(zhí)行時(shí)的真實(shí)掃描行數(shù)。
優(yōu)化器的核心任務(wù)是選擇最優(yōu)執(zhí)行計(jì)劃(如全表掃描還是索引掃描、多表連接的順序等),而rows
值是優(yōu)化器判斷成本的重要依據(jù)。例如,對(duì)于一個(gè)簡(jiǎn)單的過濾查詢,優(yōu)化器會(huì)比較 “全表掃描估計(jì)的 rows” 和 “索引掃描估計(jì)的 rows”,選擇成本更低的方案。因此,rows
的準(zhǔn)確性直接影響優(yōu)化器決策的合理性。
MySQL 優(yōu)化器之所以能 “估計(jì)” 行數(shù),依賴于數(shù)據(jù)庫(kù)收集的統(tǒng)計(jì)信息(statistics)。這些信息存儲(chǔ)在系統(tǒng)表中(如mysql.innodb_index_stats
、mysql.innodb_table_stats
),記錄了表、索引、列的數(shù)據(jù)分布特征。統(tǒng)計(jì)信息是rows
計(jì)算的 “原始數(shù)據(jù)”,主要包括以下關(guān)鍵指標(biāo):
總行數(shù)(table_rows):表中記錄的估計(jì)總數(shù)量。對(duì)于 InnoDB 表,這個(gè)值并非實(shí)時(shí)精確值,而是通過采樣計(jì)算的近似值(具體采樣邏輯后文詳述)。
數(shù)據(jù)長(zhǎng)度(data_length):表數(shù)據(jù)占用的存儲(chǔ)空間,用于輔助判斷表的 “大小”。
基數(shù)(Cardinality):索引列中不重復(fù)值的估計(jì)數(shù)量。例如,一個(gè)性別列(值為 “男”“女”)的基數(shù)約為 2,而一個(gè)用戶 ID 列的基數(shù)接近表的總行數(shù)?;鶖?shù)直接影響索引的 “選擇性”(Selectivity,即不重復(fù)值占總行數(shù)的比例),選擇性越高(基數(shù)越大),索引過濾效果越好。
rows
的計(jì)算方式并非一成不變,而是根據(jù)查詢操作的類型(如全表掃描、索引掃描、連接查詢)動(dòng)態(tài)調(diào)整。以下是常見場(chǎng)景的計(jì)算邏輯:
當(dāng)查詢無法使用索引(如無合適索引、條件過于寬泛)時(shí),優(yōu)化器會(huì)選擇全表掃描,此時(shí)rows
的估計(jì)值主要基于表級(jí)統(tǒng)計(jì)信息中的總行數(shù)(table_rows)。
例如,對(duì)于一張user
表,table_rows
統(tǒng)計(jì)值為 10000,執(zhí)行EXPLAIN SELECT * FROM user
時(shí),rows
列通常會(huì)接近 10000。但需注意:table_rows
是 InnoDB 通過采樣計(jì)算的近似值(默認(rèn)采樣 8 個(gè)數(shù)據(jù)頁(yè)),若表數(shù)據(jù)分布不均或采樣偏差,rows
可能與實(shí)際總行數(shù)存在差異。
當(dāng)查詢使用索引時(shí),rows
的計(jì)算依賴于索引的基數(shù)、選擇性及查詢條件,核心公式可簡(jiǎn)化為:
估計(jì)掃描行數(shù) = 索引過濾后的基數(shù) × 數(shù)據(jù)分布系數(shù)  
具體場(chǎng)景如下:
等值查詢(ref 類型):如WHERE age = 30
,優(yōu)化器會(huì)先通過索引統(tǒng)計(jì)獲取age
列的基數(shù),計(jì)算 “值 = 30” 的選擇性(即該值在列中的占比),再用表總行數(shù)乘以選擇性,得到估計(jì)行數(shù)。
例:
例:user
表總行數(shù) 10000,age
列基數(shù)為 50(假設(shè)年齡分布在 18-67 歲,共 50 個(gè)可能值),則 “age=30” 的選擇性約為 1/50,估計(jì)行數(shù)為 10000 × (1/50) = 200。
范圍查詢(range 類型):如WHERE price BETWEEN 100 AND 500
,優(yōu)化器會(huì)結(jié)合索引的直方圖統(tǒng)計(jì)(若啟用)或索引值的分布范圍,估算范圍內(nèi)的值占總基數(shù)的比例,再乘以總行數(shù)。
例:
例:product
表總行數(shù) 50000,price
列索引基數(shù)為 10000,若統(tǒng)計(jì)顯示 “100-500 元” 的價(jià)格占比約 20%,則估計(jì)行數(shù)為 50000 × 20% = 10000。
索引全掃描(index 類型):當(dāng)查詢需要掃描整個(gè)索引(如SELECT COUNT(*) FROM user USE INDEX(age_idx)
),rows
值接近索引的總記錄數(shù),該值基于索引的統(tǒng)計(jì)信息(如innodb_index_stats
中的sum_of_rows
)。
多表連接時(shí),rows
的計(jì)算更為復(fù)雜,優(yōu)化器需估計(jì)每一步連接的 “驅(qū)動(dòng)表” 和 “被驅(qū)動(dòng)表” 的掃描行數(shù),核心邏輯基于嵌套循環(huán)連接的成本模型:
總估計(jì)行數(shù) = 驅(qū)動(dòng)表估計(jì)行數(shù) × 被驅(qū)動(dòng)表單條驅(qū)動(dòng)記錄的匹配行數(shù)  
例如,SELECT * FROM order o JOIN user u ON o.user_id = ``u.id
,優(yōu)化器會(huì)先確定驅(qū)動(dòng)表(如order
表,估計(jì)行數(shù) 1000),再根據(jù)user
表中id
索引的基數(shù),計(jì)算每條order
記錄匹配的user
記錄數(shù)(假設(shè)id
是主鍵,基數(shù) = 總行數(shù),匹配行數(shù) = 1),則總rows
估計(jì)為 1000 × 1 = 1000。
實(shí)際使用中,rows
估計(jì)值與真實(shí)值的偏差往往源于以下因素,需重點(diǎn)關(guān)注:
MySQL 的統(tǒng)計(jì)信息默認(rèn)通過采樣更新(InnoDB 默認(rèn)每 10% 數(shù)據(jù)變更觸發(fā)自動(dòng)更新,或通過ANALYZE TABLE
手動(dòng)更新)。若表數(shù)據(jù)頻繁插入、刪除或更新,統(tǒng)計(jì)信息未及時(shí)更新,會(huì)導(dǎo)致table_rows
、基數(shù)等指標(biāo)失真,進(jìn)而影響rows
估計(jì)。
例如,一張表剛插入 10 萬(wàn)條新數(shù)據(jù)但未更新統(tǒng)計(jì)信息,優(yōu)化器仍使用舊的table_rows
(如 5 萬(wàn)),此時(shí)rows
估計(jì)會(huì)遠(yuǎn)小于實(shí)際值。
當(dāng)列數(shù)據(jù)存在 “長(zhǎng)尾分布”(如某值占比 90%,其他值共占 10%),采樣統(tǒng)計(jì)可能無法準(zhǔn)確捕捉分布特征。例如,status
列中 90% 的值為 “normal”,10% 為 “error”,優(yōu)化器基于采樣可能誤判 “status='normal'” 的選擇性為 50%,導(dǎo)致rows
估計(jì)偏差。
若索引存在重復(fù)值過多(選擇性低)、索引碎片嚴(yán)重等問題,優(yōu)化器可能低估或高估索引掃描的行數(shù)。例如,對(duì)一個(gè)選擇性極低的索引(如性別列)執(zhí)行查詢,優(yōu)化器可能認(rèn)為 “索引掃描 rows” 與 “全表掃描 rows” 接近,進(jìn)而選擇全表掃描,導(dǎo)致執(zhí)行計(jì)劃不符合預(yù)期。
對(duì)于包含子查詢、聚合函數(shù)(GROUP BY
)、排序(ORDER BY
)的復(fù)雜查詢,優(yōu)化器需對(duì)多個(gè)步驟的rows
進(jìn)行估計(jì),誤差會(huì)逐步累積,導(dǎo)致最終rows
值與實(shí)際偏差較大。
要讓rows
值更接近實(shí)際掃描行數(shù),需從統(tǒng)計(jì)信息維護(hù)、數(shù)據(jù)設(shè)計(jì)和查詢優(yōu)化三方面入手:
對(duì)頻繁變更的表定期執(zhí)行ANALYZE TABLE table_name
,強(qiáng)制更新統(tǒng)計(jì)信息(InnoDB 會(huì)重新采樣計(jì)算table_rows
、基數(shù)等)。
調(diào)整統(tǒng)計(jì)信息采樣參數(shù):通過innodb_stats_persistent_sample_pages
(持久化統(tǒng)計(jì)采樣頁(yè)數(shù)量,默認(rèn) 20)或innodb_stats_transient_sample_pages
(臨時(shí)統(tǒng)計(jì)采樣頁(yè)數(shù)量,默認(rèn) 8)提高采樣精度(需權(quán)衡性能開銷)。
避免在低選擇性列上創(chuàng)建索引(如性別、狀態(tài)等),此類索引對(duì)rows
估計(jì)和查詢效率提升有限。
對(duì)高選擇性列(如用戶 ID、訂單號(hào))建立索引,并通過SHOW INDEX FROM table_name
定期檢查索引基數(shù)是否合理。
若rows
估計(jì)值與實(shí)際掃描行數(shù)偏差較大(可通過SHOW PROFILE
或慢查詢?nèi)罩静榭磳?shí)際行數(shù)),嘗試改寫查詢(如調(diào)整過濾條件順序、避免子查詢嵌套過深)。
對(duì)復(fù)雜連接查詢,通過STRAIGHT_JOIN
指定連接順序,避免優(yōu)化器因rows
估計(jì)錯(cuò)誤選擇低效連接方式。
某電商平臺(tái)的訂單查詢 SQL 執(zhí)行緩慢,EXPLAIN
輸出顯示rows
估計(jì)為 1000,但實(shí)際掃描行數(shù)達(dá) 10 萬(wàn)。排查發(fā)現(xiàn):
訂單表order
近期新增 50 萬(wàn)條數(shù)據(jù),但未執(zhí)行ANALYZE TABLE
,table_rows
仍為舊值 10 萬(wàn),導(dǎo)致優(yōu)化器低估總行數(shù);
過濾條件WHERE create_time > '2023-01-01'
使用的create_time
索引存在大量碎片,基數(shù)統(tǒng)計(jì)失真,優(yōu)化器誤判范圍查詢的選擇性為 1%(實(shí)際為 20%)。
解決方法:
執(zhí)行ANALYZE TABLE order
更新統(tǒng)計(jì)信息,table_rows
修正為 60 萬(wàn);
重建create_time
索引(ALTER TABLE order REBUILD INDEX create_time_idx
),修復(fù)碎片并更新基數(shù);
優(yōu)化后,rows
估計(jì)值為 12000(60 萬(wàn) × 20%),與實(shí)際掃描行數(shù)(11 萬(wàn))接近,優(yōu)化器選擇了更合理的索引掃描計(jì)劃,查詢性能提升 80%。
MySQL 執(zhí)行計(jì)劃中的rows
值是優(yōu)化器基于統(tǒng)計(jì)信息和數(shù)據(jù)分布的 “智能預(yù)測(cè)”,其計(jì)算邏輯貫穿查詢執(zhí)行的全流程。理解rows
的來源、影響因素及優(yōu)化方法,不僅能幫助開發(fā)者快速定位查詢性能瓶頸,更能深入掌握 MySQL 優(yōu)化器的工作原理。在實(shí)際工作中,需結(jié)合EXPLAIN
輸出、統(tǒng)計(jì)信息維護(hù)和數(shù)據(jù)特征分析,讓rows
成為查詢優(yōu)化的 “指路明燈”,而非誤導(dǎo)決策的 “迷霧”。
數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼
若不方便掃碼,搜微信號(hào):CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實(shí)戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫(kù)管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫(kù)表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動(dòng)態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價(jià)值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫(kù)表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實(shí)戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫(kù))處理 Excel 數(shù)據(jù)時(shí),“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗(yàn)與 t 檢驗(yàn):差異、適用場(chǎng)景與實(shí)踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計(jì)學(xué)領(lǐng)域,假設(shè)檢驗(yàn)是驗(yàn)證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計(jì)劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計(jì)劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對(duì)象的 text 與 content:區(qū)別、場(chǎng)景與實(shí)踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請(qǐng)求開發(fā)時(shí)(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價(jià)值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫(kù)表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請(qǐng)求工具對(duì)比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請(qǐng)求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長(zhǎng)浮點(diǎn)數(shù)據(jù)的科學(xué)計(jì)數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長(zhǎng)浮點(diǎn)數(shù)據(jù)時(shí)的科學(xué)計(jì)數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價(jià)值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運(yùn)營(yíng)問題、提升執(zhí)行效率的核心手段,其價(jià)值 ...
2025-09-12用 SQL 驗(yàn)證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實(shí)戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計(jì)” 與 “用戶體驗(yàn) ...
2025-09-11塔吉特百貨孕婦營(yíng)銷案例:數(shù)據(jù)驅(qū)動(dòng)下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營(yíng)銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價(jià)值 在數(shù)據(jù)驅(qū)動(dòng)決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實(shí)踐到業(yè)務(wù)價(jià)值挖掘 在數(shù)據(jù)分析場(chǎng)景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計(jì)模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價(jià)值導(dǎo)向 統(tǒng)計(jì)模型作為數(shù)據(jù)分析的核心工具,并非簡(jiǎn)單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10