簡體   English   中英

MySQL:對ANALYZE TABLE的隨機影響

[英]MySQL: random effect on ANALYZE TABLE

我有3個innodb表,例如A,B和C。有一個查詢將這三個表連接起來以生成結果。

SELECT A.a, B.b, C.c
from A 
join B on A.id = B.a_id 
join C on C.id = B.c_id
where A.a = 'example' and B.b < 10;

在開始使用“ EXPLAIN”命令測試查詢時,它給我以下順序:

B-C-A

但是,這不是最佳的。 所以我對所有表運行“ ANALYZE TABLE”,它給了我:

A-B-C

,我認為這是正確的順序。

然后,我將SQL部署到生產環境中,在沒有理由的情況下,一個月后,執行計划又切換回錯誤的選項,即B--C--A。 在那之后,我嘗試再次運行ANALYZE TABLE 幾次 ,但是這次,結果讓我感到困惑。 有時它也給了我B–C–A,有時它給了我A–B–C,有時甚至是其他執行計划。

所以我的問題是:

  1. 為什么執行計划在部署后會發生變化?
  2. 除了固定執行計划(數據會更新並快速更改,因此最佳計划將來可能會更改)之外,是否有辦法保證始終確保最佳計划?

優化器根據有關表大小,基數,值的分布,索引等的內存中統計信息來選擇對表進行重新排序和使用索引的方法。這些統計信息是估計值 ,並非始終都是絕對准確的。

InnoDB會不時更新其統計信息,這就是您運行ANALZYE TABLE時可能導致的情況。

但是,在某些情況下,內存中的統計信息正處於使優化器做出不同選擇的時刻,因此您會看到這種觸發器行為。

通過在查詢中指定索引提示 ,可以覆蓋優化程序的默認算法來選擇索引。

您可以通過指定STRAIGHT_JOIN來覆蓋優化程序的默認算法來對表進行重新排序。 這意味着您希望它按您在FROM子句中給它們的順序讀取表,而不要對其重新排序。

您可以將STRAIGHT_JOIN用作查詢修飾符(例如DISTINCT)。 將其放在SELECT之后:

SELECT STRAIGHT_JOIN A.a, B.b, C.c
from A 
join B on A.id = B.a_id 
join C on C.id = B.c_id
where A.a = 'example' and B.b < 10;

但請謹慎使用索引提示或聯接提示。 在數據的大小和分布發生一點點變化之后,優化器可能會在下周避免觸發行為。 如果您的代碼中有太多替代,您可能會阻止優化器做得更好!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM