Mysql

Mysql 將使用者名與客戶端表分開以提高性能並使用 myisam

  • March 16, 2020

我正在為像 Telegram 這樣的非常重的信使創建一個數據庫……我決定為客戶端使用者名使用不同的表並將其與客戶端表分開。

這是我的“客戶”表:

InnoDB (because we are going to have too many updates over select !)
ascii_general_ci

    ID       -> int (unsigned parimary auto-index)
    password -> char (64) (not-null ('char' get us better performance over 'varchar' since password-length is fixed-length (64) (because of hash))
    ...

這是我的“client_username”表:

MyISAM (because we are going to have too many SELECT over update !)
ascii_general_ci


    client_ID       -> int (unsigned unique)
    client_username -> char (16) (using 'char' for better performance duo to it's fixed-length type. also it's better to use 'char' type in MyISAM type)

我分隔了使用者名,因為客戶端表是 InnoDB,它在 SELECT 中不如 MyISAM。所以我將使用者名分隔到一個 MyISAM 類型的表中。在這裡,我們在搜尋使用者名方面表現最好,而且我這樣做是因為我想為我的使用者名選擇 ‘char’ 類型,而且我聽說 ‘char’ 類型在 ‘MyISAM’ 類型中比 varchar nly 快。我對所有這些觀點都是正確的嗎?

MyISAM 與 InnoDB 的神話

“InnoDB 不如 MyISAM”

那是一個老婦人的故事。把它從你的腦海中抹去。

  • 自從傳聞開始以來,InnoDB 已經有了很大的改進。
  • 您現在將使用者資訊拆分到兩個表中;這樣做的小成本可能比將所有資訊整齊地放在一個 InnoDB 表中更糟糕。

底線: 對所有表使用 InnoDB。 這個簡單的規則很少有例外。沒有特別的順序:

  • InnoDB 表通常具有 2x-3x 更大的磁碟佔用空間。但是,那又怎樣,磁碟是巨大的。
  • COUNT(*)withoutWHERE在 MyISAM 中是“即時的”。
  • 2-col AUTO_INCREMENT– MyISAM 中的標準;在 InnoDB 中模擬很笨拙。(很少要求。)
  • 在晦澀的情況下表現。(目前沒有具體的想法。)
  • 有人可能會爭辯說,這些差異FULLTEXT構成了一個問題。

另一方面,甲骨文表明 MyISAM 將從 MySQL 中移除。


CHAR vs VARCHAR 神話

CHARVARCHAR”好

另一個 _old_wives 的故事。即使在 MyISAM 中,這句話也經常被斷章取義。

  • 即使在上下文中它也很少有效
  • 如果您有可變長度數據,則 I/O 的節省高於所謂的CHARover節省VARCHAR
  • 在 InnoDB 中,CHAR大部分VARCHAR實現是相同的。

底線: 僅用於真正固定長度的字元串**。CHAR**


需要優化小事的神話

我先從“答案”開始。

甚至在查看數據之前,還有其他任務。

  1. 接收查詢,可能通過 WAN。(最多毫秒。)
  2. 解析查詢中的標記。
  3. 找出查詢中命名的每一列正在使用哪個表。
  4. 打開表。
  5. 呼叫優化器來推斷執行查詢的最佳方式。這將涉及定位所有可能的索引,對錶進行探測以收集統計資訊等。
  6. 執行查詢。

在宏偉的計劃中,查找記錄的成本遠遠高於使用記錄所做的任何事情。(這是一個概括,不是絕對的。)

  1. 找到記錄——也許是通過索引,也許是“下一個”獲取的最後一條記錄。
  2. 獲取包含記錄的塊。這可能記憶體在緩衝池中,但可能需要從磁碟中獲取。所以,這一步可能是納秒,也可能是毫秒。
  3. 剖析塊以找到有問題的行。如果多個事務正在執行,這可能包括掃描“歷史列表”,並且需要參考“隔離模式”來確定行的哪個副本是“可見的”。
  4. 既然您有了行,就需要將列分開——即使存在字外邊界問題、字節掃描、NULL檢查、長度檢查​​(例如 forVARchar等,我們說的是每列納秒。
  5. “字節序”在這裡出現。MySQL 可以處理具有二進制兼容性的 big-endian 和 little-endian 硬體架構。這意味著對於某些依賴於硬體的情況,它必須交換字節才能將列值轉換為正確的“字節序”。
  6. 對列做一些事情。這可能只是原封不動地複制它;它可能正在應用一個函式(整理、求和、sqrt 等)。再次納秒。

現在,你的問題是什麼?哦,是的,你擔心最後一步的一小部分。


一般的

  • 由於各種硬體、軟體和設計原因,字邊界不值得考慮。
  • 對於大型表,I/O 是比固定長度和可變長度的事物更大的性能因素。
  • MyISAM 中的固定長度幾乎沒有什麼優勢。當你不做UPDATEDELETE+時,大多數都會消失INSERT
  • 一行中的所有列都需要“固定”,否則它是“可變的”。
  • InnoDB 可能從“固定”中獲得零收益。
  • MyISAM 是在添加可變長度字元集(utf8 等)之前設計的。使用 utf8 時, EvenCHAR的長度實際上是可變的。

(並且停止閱讀任何超過十年的 MySQL 參考資料。)

引用自:https://dba.stackexchange.com/questions/262002