儲存引擎會收集資料表統計資料,供最佳化工具使用。資料表統計資料以值群組為基礎,其中值群組是一組具有相同索引鍵前置值之資料列的集合。對於最佳化工具而言,一個重要的統計資料是平均值群組大小。
MySQL 以下列方式使用平均值群組大小
估計每個
ref存取必須讀取多少資料列估計部分聯結產生多少資料列,也就是由下列形式的操作所產生的資料列數目
(...) JOIN tbl_name ON tbl_name.key = expr
隨著索引的平均值群組大小增加,索引對於這兩個用途的效用會降低,因為每次查閱的平均資料列數目會增加:為了使索引適用於最佳化用途,最好每個索引值都針對資料表中的少量資料列。當給定索引值產生大量資料列時,索引的效用會降低,而且 MySQL 較不可能使用它。
平均值群組大小與資料表基數相關,基數是值群組的數目。SHOW INDEX 陳述式會根據 N/S 顯示基數值,其中 N 是資料表中的資料列數目,而 S 是平均值群組大小。該比例會產生資料表中值群組的近似數目。
對於以 <=> 比較運算子為基礎的聯結,NULL 的處理方式與任何其他值都相同:NULL <=> NULL,就像任何其他 N 的 一樣。N <=> N
然而,對於以 = 運算子為基礎的聯結,NULL 與非 NULL 值不同:當 expr1 或 expr2 (或兩者) 為 NULL 時, 不成立。這會影響 expr1 = expr2ref 存取,以進行 形式的比較:如果 tbl_name.key = exprexpr 的目前值為 NULL,則 MySQL 不會存取資料表,因為比較不可能成立。
對於 = 比較,資料表中有多少 NULL 值並不重要。對於最佳化用途,相關的值是非 NULL 值群組的平均大小。然而,MySQL 目前未啟用收集或使用該平均大小。
對於 InnoDB 和 MyISAM 資料表,您可以使用 innodb_stats_method 和 myisam_stats_method 系統變數,分別對資料表統計資料的收集進行一些控制。這些變數有三個可能的值,其差異如下
當變數設定為
nulls_equal時,所有NULL值都會被視為相同 (也就是說,它們都形成單一值群組)。如果
NULL值群組的大小遠大於平均非NULL值群組的大小,此方法會使平均值群組大小向上傾斜。這會使索引對最佳化器而言,在尋找非NULL值的聯結中,看起來比實際上較無用。因此,nulls_equal方法可能會導致最佳化器在應該使用索引進行ref存取時,不使用索引。當變數設定為
nulls_unequal時,NULL值不被視為相同。相反地,每個NULL值都會形成一個大小為 1 的獨立值群組。如果您有很多
NULL值,此方法會使平均值群組大小向下傾斜。如果平均非NULL值群組的大小很大,將每個NULL值都視為大小為 1 的群組,會導致最佳化器高估索引在尋找非NULL值的聯結中的價值。因此,nulls_unequal方法可能會導致最佳化器在其他方法可能更好的情況下,使用此索引進行ref查詢。當變數設定為
nulls_ignored時,NULL值會被忽略。
如果您傾向於使用許多使用 <=> 而不是 = 的聯結,那麼 NULL 值在比較中並不是特殊的,一個 NULL 值等於另一個 NULL 值。在這種情況下,nulls_equal 是適當的統計方法。
innodb_stats_method 系統變數具有全域值;myisam_stats_method 系統變數同時具有全域和工作階段值。設定全域值會影響來自對應儲存引擎的表格統計資訊收集。設定工作階段值只會影響目前用戶端連線的統計資訊收集。這表示您可以透過設定 myisam_stats_method 的工作階段值,強制使用指定的方法重新產生表格的統計資訊,而不會影響其他用戶端。
要重新產生 MyISAM 表格統計資訊,您可以使用下列任何方法
變更表格使其統計資訊過時(例如,插入一行然後刪除它),然後設定
myisam_stats_method並發出ANALYZE TABLE陳述式
關於使用 innodb_stats_method 和 myisam_stats_method 的一些注意事項
您可以如剛才所述,強制明確收集表格統計資訊。但是,MySQL 也可能會自動收集統計資訊。例如,如果在執行表格陳述式的過程中,其中一些陳述式修改了表格,MySQL 就可能會收集統計資訊。(這可能會發生在大量插入或刪除,或某些
ALTER TABLE陳述式中,例如。)如果發生這種情況,統計資訊會使用當時innodb_stats_method或myisam_stats_method的任何值來收集。因此,如果您使用一種方法收集統計資訊,但當稍後自動收集表格的統計資訊時,系統變數設定為另一種方法,則會使用另一種方法。無法判斷用於產生特定表格統計資訊的方法。
這些變數僅適用於
InnoDB和MyISAM表格。其他儲存引擎只有一種收集表格統計資訊的方法。通常它更接近nulls_equal方法。