
在 MySQL 數(shù)據(jù)庫的查詢優(yōu)化中,執(zhí)行計劃(EXPLAIN
輸出)是開發(fā)者和 DBA 分析查詢性能的核心工具。其中,rows
列作為執(zhí)行計劃的關(guān)鍵指標(biāo),代表優(yōu)化器估計的當(dāng)前操作需要掃描的行數(shù)。這個數(shù)值直接反映了查詢的效率 —— 行數(shù)越少,查詢通常越高效。但很多人對這個數(shù)值的計算邏輯感到困惑:它究竟是怎么來的?為何有時會與實際掃描行數(shù)相差較大?本文將從原理到實踐,全面解析 MySQL 執(zhí)行計劃中rows
的計算邏輯。
在深入計算邏輯前,需先明確rows
的本質(zhì):它是 MySQL 優(yōu)化器基于統(tǒng)計信息和數(shù)據(jù)分布規(guī)律,對查詢執(zhí)行過程中需要訪問的行數(shù)的 “預(yù)測值”,而非實際執(zhí)行時的真實掃描行數(shù)。
優(yōu)化器的核心任務(wù)是選擇最優(yōu)執(zhí)行計劃(如全表掃描還是索引掃描、多表連接的順序等),而rows
值是優(yōu)化器判斷成本的重要依據(jù)。例如,對于一個簡單的過濾查詢,優(yōu)化器會比較 “全表掃描估計的 rows” 和 “索引掃描估計的 rows”,選擇成本更低的方案。因此,rows
的準(zhǔn)確性直接影響優(yōu)化器決策的合理性。
MySQL 優(yōu)化器之所以能 “估計” 行數(shù),依賴于數(shù)據(jù)庫收集的統(tǒng)計信息(statistics)。這些信息存儲在系統(tǒng)表中(如mysql.innodb_index_stats
、mysql.innodb_table_stats
),記錄了表、索引、列的數(shù)據(jù)分布特征。統(tǒng)計信息是rows
計算的 “原始數(shù)據(jù)”,主要包括以下關(guān)鍵指標(biāo):
總行數(shù)(table_rows):表中記錄的估計總數(shù)量。對于 InnoDB 表,這個值并非實時精確值,而是通過采樣計算的近似值(具體采樣邏輯后文詳述)。
數(shù)據(jù)長度(data_length):表數(shù)據(jù)占用的存儲空間,用于輔助判斷表的 “大小”。
基數(shù)(Cardinality):索引列中不重復(fù)值的估計數(shù)量。例如,一個性別列(值為 “男”“女”)的基數(shù)約為 2,而一個用戶 ID 列的基數(shù)接近表的總行數(shù)。基數(shù)直接影響索引的 “選擇性”(Selectivity,即不重復(fù)值占總行數(shù)的比例),選擇性越高(基數(shù)越大),索引過濾效果越好。
rows
的計算方式并非一成不變,而是根據(jù)查詢操作的類型(如全表掃描、索引掃描、連接查詢)動態(tài)調(diào)整。以下是常見場景的計算邏輯:
當(dāng)查詢無法使用索引(如無合適索引、條件過于寬泛)時,優(yōu)化器會選擇全表掃描,此時rows
的估計值主要基于表級統(tǒng)計信息中的總行數(shù)(table_rows)。
例如,對于一張user
表,table_rows
統(tǒng)計值為 10000,執(zhí)行EXPLAIN SELECT * FROM user
時,rows
列通常會接近 10000。但需注意:table_rows
是 InnoDB 通過采樣計算的近似值(默認(rèn)采樣 8 個數(shù)據(jù)頁),若表數(shù)據(jù)分布不均或采樣偏差,rows
可能與實際總行數(shù)存在差異。
當(dāng)查詢使用索引時,rows
的計算依賴于索引的基數(shù)、選擇性及查詢條件,核心公式可簡化為:
估計掃描行數(shù) = 索引過濾后的基數(shù) × 數(shù)據(jù)分布系數(shù)  
具體場景如下:
等值查詢(ref 類型):如WHERE age = 30
,優(yōu)化器會先通過索引統(tǒng)計獲取age
列的基數(shù),計算 “值 = 30” 的選擇性(即該值在列中的占比),再用表總行數(shù)乘以選擇性,得到估計行數(shù)。
例:
例:user
表總行數(shù) 10000,age
列基數(shù)為 50(假設(shè)年齡分布在 18-67 歲,共 50 個可能值),則 “age=30” 的選擇性約為 1/50,估計行數(shù)為 10000 × (1/50) = 200。
范圍查詢(range 類型):如WHERE price BETWEEN 100 AND 500
,優(yōu)化器會結(jié)合索引的直方圖統(tǒng)計(若啟用)或索引值的分布范圍,估算范圍內(nèi)的值占總基數(shù)的比例,再乘以總行數(shù)。
例:
例:product
表總行數(shù) 50000,price
列索引基數(shù)為 10000,若統(tǒng)計顯示 “100-500 元” 的價格占比約 20%,則估計行數(shù)為 50000 × 20% = 10000。
索引全掃描(index 類型):當(dāng)查詢需要掃描整個索引(如SELECT COUNT(*) FROM user USE INDEX(age_idx)
),rows
值接近索引的總記錄數(shù),該值基于索引的統(tǒng)計信息(如innodb_index_stats
中的sum_of_rows
)。
多表連接時,rows
的計算更為復(fù)雜,優(yōu)化器需估計每一步連接的 “驅(qū)動表” 和 “被驅(qū)動表” 的掃描行數(shù),核心邏輯基于嵌套循環(huán)連接的成本模型:
總估計行數(shù) = 驅(qū)動表估計行數(shù) × 被驅(qū)動表單條驅(qū)動記錄的匹配行數(shù)  
例如,SELECT * FROM order o JOIN user u ON o.user_id = ``u.id
,優(yōu)化器會先確定驅(qū)動表(如order
表,估計行數(shù) 1000),再根據(jù)user
表中id
索引的基數(shù),計算每條order
記錄匹配的user
記錄數(shù)(假設(shè)id
是主鍵,基數(shù) = 總行數(shù),匹配行數(shù) = 1),則總rows
估計為 1000 × 1 = 1000。
實際使用中,rows
估計值與真實值的偏差往往源于以下因素,需重點關(guān)注:
MySQL 的統(tǒng)計信息默認(rèn)通過采樣更新(InnoDB 默認(rèn)每 10% 數(shù)據(jù)變更觸發(fā)自動更新,或通過ANALYZE TABLE
手動更新)。若表數(shù)據(jù)頻繁插入、刪除或更新,統(tǒng)計信息未及時更新,會導(dǎo)致table_rows
、基數(shù)等指標(biāo)失真,進而影響rows
估計。
例如,一張表剛插入 10 萬條新數(shù)據(jù)但未更新統(tǒng)計信息,優(yōu)化器仍使用舊的table_rows
(如 5 萬),此時rows
估計會遠小于實際值。
當(dāng)列數(shù)據(jù)存在 “長尾分布”(如某值占比 90%,其他值共占 10%),采樣統(tǒng)計可能無法準(zhǔn)確捕捉分布特征。例如,status
列中 90% 的值為 “normal”,10% 為 “error”,優(yōu)化器基于采樣可能誤判 “status='normal'” 的選擇性為 50%,導(dǎo)致rows
估計偏差。
若索引存在重復(fù)值過多(選擇性低)、索引碎片嚴(yán)重等問題,優(yōu)化器可能低估或高估索引掃描的行數(shù)。例如,對一個選擇性極低的索引(如性別列)執(zhí)行查詢,優(yōu)化器可能認(rèn)為 “索引掃描 rows” 與 “全表掃描 rows” 接近,進而選擇全表掃描,導(dǎo)致執(zhí)行計劃不符合預(yù)期。
對于包含子查詢、聚合函數(shù)(GROUP BY
)、排序(ORDER BY
)的復(fù)雜查詢,優(yōu)化器需對多個步驟的rows
進行估計,誤差會逐步累積,導(dǎo)致最終rows
值與實際偏差較大。
要讓rows
值更接近實際掃描行數(shù),需從統(tǒng)計信息維護、數(shù)據(jù)設(shè)計和查詢優(yōu)化三方面入手:
對頻繁變更的表定期執(zhí)行ANALYZE TABLE table_name
,強制更新統(tǒng)計信息(InnoDB 會重新采樣計算table_rows
、基數(shù)等)。
調(diào)整統(tǒng)計信息采樣參數(shù):通過innodb_stats_persistent_sample_pages
(持久化統(tǒng)計采樣頁數(shù)量,默認(rèn) 20)或innodb_stats_transient_sample_pages
(臨時統(tǒng)計采樣頁數(shù)量,默認(rèn) 8)提高采樣精度(需權(quán)衡性能開銷)。
若rows
估計值與實際掃描行數(shù)偏差較大(可通過SHOW PROFILE
或慢查詢?nèi)罩静榭磳嶋H行數(shù)),嘗試改寫查詢(如調(diào)整過濾條件順序、避免子查詢嵌套過深)。
對復(fù)雜連接查詢,通過STRAIGHT_JOIN
指定連接順序,避免優(yōu)化器因rows
估計錯誤選擇低效連接方式。
某電商平臺的訂單查詢 SQL 執(zhí)行緩慢,EXPLAIN
輸出顯示rows
估計為 1000,但實際掃描行數(shù)達 10 萬。排查發(fā)現(xiàn):
訂單表order
近期新增 50 萬條數(shù)據(jù),但未執(zhí)行ANALYZE TABLE
,table_rows
仍為舊值 10 萬,導(dǎo)致優(yōu)化器低估總行數(shù);
過濾條件WHERE create_time > '2023-01-01'
使用的create_time
索引存在大量碎片,基數(shù)統(tǒng)計失真,優(yōu)化器誤判范圍查詢的選擇性為 1%(實際為 20%)。
解決方法:
執(zhí)行ANALYZE TABLE order
更新統(tǒng)計信息,table_rows
修正為 60 萬;
重建create_time
索引(ALTER TABLE order REBUILD INDEX create_time_idx
),修復(fù)碎片并更新基數(shù);
優(yōu)化后,rows
估計值為 12000(60 萬 × 20%),與實際掃描行數(shù)(11 萬)接近,優(yōu)化器選擇了更合理的索引掃描計劃,查詢性能提升 80%。
MySQL 執(zhí)行計劃中的rows
值是優(yōu)化器基于統(tǒng)計信息和數(shù)據(jù)分布的 “智能預(yù)測”,其計算邏輯貫穿查詢執(zhí)行的全流程。理解rows
的來源、影響因素及優(yōu)化方法,不僅能幫助開發(fā)者快速定位查詢性能瓶頸,更能深入掌握 MySQL 優(yōu)化器的工作原理。在實際工作中,需結(jié)合EXPLAIN
輸出、統(tǒng)計信息維護和數(shù)據(jù)特征分析,讓rows
成為查詢優(yōu)化的 “指路明燈”,而非誤導(dǎo)決策的 “迷霧”。
你是不是也經(jīng)常刷到別人漲粉百萬、帶貨千萬,心里癢癢的,想著“我也試試”,結(jié)果三個月過去,粉絲不到1000,播放量慘不忍睹? ...
2025-07-21我是陳輝,一個創(chuàng)業(yè)十多年的企業(yè)主,前半段人生和“文字”緊緊綁在一起。從廣告公司文案到品牌策劃,再到自己開策劃機構(gòu),我靠 ...
2025-07-21左偏態(tài)分布轉(zhuǎn)正態(tài)分布:方法、原理與實踐 左偏態(tài)分布轉(zhuǎn)正態(tài)分布:方法、原理與實踐 在統(tǒng)計分析、數(shù)據(jù)建模和科學(xué)研究中,正態(tài)分 ...
2025-07-21CDA 數(shù)據(jù)分析師的職業(yè)生涯規(guī)劃:從入門到卓越的成長之路 在數(shù)字經(jīng)濟蓬勃發(fā)展的當(dāng)下,數(shù)據(jù)已成為企業(yè)核心競爭力的重要來源,而 CD ...
2025-07-21MySQL執(zhí)行計劃中rows的計算邏輯:從原理到實踐 MySQL 執(zhí)行計劃中 rows 的計算邏輯:從原理到實踐 在 MySQL 數(shù)據(jù)庫的查詢優(yōu)化中 ...
2025-07-21在AI滲透率超85%的2025年,企業(yè)生存之戰(zhàn)就是數(shù)據(jù)之戰(zhàn),CDA認(rèn)證已成為決定企業(yè)存續(xù)的生死線!據(jù)麥肯錫全球研究院數(shù)據(jù)顯示,AI驅(qū) ...
2025-07-2035歲焦慮像一把高懸的利刃,裁員潮、晉升無望、技能過時……當(dāng)職場中年危機與數(shù)字化浪潮正面交鋒,你是否發(fā)現(xiàn): 簡歷投了10 ...
2025-07-20CDA 數(shù)據(jù)分析師報考條件詳解與準(zhǔn)備指南? ? 在數(shù)據(jù)驅(qū)動決策的時代浪潮下,CDA 數(shù)據(jù)分析師認(rèn)證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-18剛?cè)肼殘龌蚴窃诼殘稣媾R崗位替代、技能更新、人機協(xié)作等焦慮的打工人,想要找到一條破解職場焦慮和升職瓶頸的系統(tǒng)化學(xué)習(xí)提升 ...
2025-07-182025被稱為“AI元年”,而AI,與數(shù)據(jù)密不可分。網(wǎng)易公司創(chuàng)始人丁磊在《AI思維:從數(shù)據(jù)中創(chuàng)造價值的煉金術(shù) ...
2025-07-18CDA 數(shù)據(jù)分析師:數(shù)據(jù)時代的價值挖掘者 在大數(shù)據(jù)席卷全球的今天,數(shù)據(jù)已成為企業(yè)核心競爭力的重要組成部分。從海量數(shù)據(jù)中提取有 ...
2025-07-18SPSS 賦值后數(shù)據(jù)不顯示?原因排查與解決指南? 在 SPSS( Statistical Package for the Social Sciences)數(shù)據(jù)分析過程中,變量 ...
2025-07-18在 DBeaver 中利用 MySQL 實現(xiàn)表數(shù)據(jù)同步操作指南? ? 在數(shù)據(jù)庫管理工作中,將一張表的數(shù)據(jù)同步到另一張表是常見需求,這有助于 ...
2025-07-18數(shù)據(jù)分析師的技能圖譜:從數(shù)據(jù)到價值的橋梁? 在數(shù)據(jù)驅(qū)動決策的時代,數(shù)據(jù)分析師如同 “數(shù)據(jù)翻譯官”,將冰冷的數(shù)字轉(zhuǎn)化為清晰的 ...
2025-07-17Pandas 寫入指定行數(shù)據(jù):數(shù)據(jù)精細化管理的核心技能? 在數(shù)據(jù)處理的日常工作中,我們常常需要面對這樣的場景:在龐大的數(shù)據(jù)集里精 ...
2025-07-17解碼 CDA:數(shù)據(jù)時代的通行證? 在數(shù)字化浪潮席卷全球的今天,當(dāng)企業(yè)決策者盯著屏幕上跳動的數(shù)據(jù)曲線尋找增長密碼,當(dāng)科研人員在 ...
2025-07-17CDA 精益業(yè)務(wù)數(shù)據(jù)分析:數(shù)據(jù)驅(qū)動業(yè)務(wù)增長的實戰(zhàn)方法論 在企業(yè)數(shù)字化轉(zhuǎn)型的浪潮中,“數(shù)據(jù)分析” 已從 “加分項” 成為 “必修課 ...
2025-07-16MySQL 中 ADD KEY 與 ADD INDEX 詳解:用法、差異與優(yōu)化實踐 在 MySQL 數(shù)據(jù)庫表結(jié)構(gòu)設(shè)計中,索引是提升查詢性能的核心手段。無論 ...
2025-07-16解析 MySQL Update 語句中 “query end” 狀態(tài):含義、成因與優(yōu)化指南? 在 MySQL 數(shù)據(jù)庫的日常運維與開發(fā)中,開發(fā)者和 DBA 常會 ...
2025-07-16如何考取數(shù)據(jù)分析師證書:以 CDA 為例? ? 在數(shù)字化浪潮席卷各行各業(yè)的當(dāng)下,數(shù)據(jù)分析師已然成為企業(yè)挖掘數(shù)據(jù)價值、驅(qū)動決策的 ...
2025-07-15