簡體   English   中英

MyISAM-> InnoDB之后,mysql查詢變慢並移至AWS

[英]mysql query slow after MyISAM -> InnoDB and move to AWS

我計划從共享的托管服務器切換到AWS設置(針對Apache / php的EC2,針對MySQL的RDS)。

我在共享服務器上運行了超過一年的PHP / mysql網站測試版。 尤其是一頁在瀏覽器中總是運行很快(完全加載可能少於3秒)。

在准備搬遷時,我將數據庫和所有表從MyISAM更改為InnoDB。 我還將默認字符集切換為utf8mb4(是latin-1或其他形式),並將排序規則切換為utf8mb4_unicode_ci。 有幾列像varchar2(400)一樣被索引的列,它們得到了> 191個字符的錯誤(因為使用utf8mb4從3byte-> 4byte轉移了)。 我進去並手動將這些列手動切換為UTF-8 / utf_unicode_ci。 一切似乎都很好(沒有明確的錯誤)

現在,我已將站點/數據庫的副本移至AWS。 大多數頁面加載正常。 特別是,它要花很長時間才能加載(> 5分鍾)。 我有一些很小的EC2實例和RDS實例,所以我意識到這可能是一個問題,但是我是唯一使用該站點(用於一個查詢)的人,整個數據庫小於70MB。

運行一個解釋計划顯示在大多數情況下使用鍵(索引?)和一個具有74k行的“派生”表。 74k是非常小的數據集。 我對Oracle的解釋計划更加熟悉,因此我很難弄清發生了什么。

我嘗試在共享托管服務器上運行原始頁面,它也變得越來越慢! 因此,我沒有理由相信這是一個AWS問題。

我知道在簡單的情況下MyISAM快一點,但是沒有辦法比我新使用的InnoDB快10000000000000x嗎?

嘗試索引大於191個字符的varchar的轉換是否出了問題? 是否有可能以某種方式破壞了系統/表? 如果您給他們很多時間,查詢將完成,但是它們不可能這么慢。 我認為即使索引被油炸,並且它正在對74k行進行全表掃描,它甚至也不會費勁。

思考?

編輯:找到了這個線程: https : //dba.stackexchange.com/questions/75091/why-are-simple-selects-on-innodb-100x-slower-than-on-myisam海報似乎也有類似的減速體驗。 我不能使用與他/她相同的解決方案。 認為我必須將要返回的所有列都放入索引是很瘋狂的。 每個人都不可能接受嗎?

好的,我知道了。 是我的錯(不足為奇)。 我很久以前才寫查詢,直到我真正知道自己在做什么。 肯定還有改進的余地...

查詢看起來像:

TableA (main table of focus)
  aID (pk)
  bID (fk)
  locationID (fk)
  rowTitle

TableB 
  bID (pk)
  locationID (fk)

TableLocations
  locationID (pk)
  locationName

我想基本上使用A的位置(如果存在),但是如果A沒有一個位置,則使用B的位置。 (A將始終鏈接到B)。

我在做一些像

 SELECT
   rowTitle,
   locationName
 FROM
   TableA a, TableB b, TableLocations loc
 WHERE
  a.bID = b.bID
  AND
  ( a.locationID = loc.locationID
    OR 
   (a.locationID IS NULL AND b.locationID = loc.locationID)
  )

它工作正常,並且在使用MyISAM時始終返回我想要的東西。 而且很快。 但是,由於某種原因,當我搬到InnoDB時,sh $&碰到了牆。 在執行此查詢的計划時,引擎沒有任何區別。 我想在某個時刻,當數據集足夠大時,MyISAM會感到窒息,但是由於我仍然在開發人員中,因此數據很小。

從那以后,我開始轉向結構更好的東西:

 SELECT 
   rowTitle
   CASE WHEN loc1.locationID IS NOT NULL THEN loc1.locationName
        WHEN loc2.locationID IS NOT NULL THEN loc2.locationName
   END as locationName
FROM
   TableA a
JOIN TableB b ON a.bID = b.bID
 LEFT OUTER JOIN TableLocations loc1 ON a.locationID = loc1.locationID
 LEFT OUTER JOIN TableLocations loc2 ON b.locationID = loc2.locationID

一切都很好! 我刪去了很多查詢和其他表,以關注我的主要邏輯/物理問題。

查詢下降到大約10MS,這是我期望的。

那是我對MySQL的愛與恨。 有時,“它確實有效”,讓您克服自己的不足。 絕對是我第一次沒有做對的錯。

附加問題:如果有人知道MyISAM與InnoDB如何評估第一個(錯誤)查詢之間的區別以及為什么性能如此不同,我真的很想聽聽它!

謝謝!

暫無
暫無

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

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