Mysql
Mysql 將使用者名與客戶端表分開以提高性能並使用 myisam
我正在為像 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 神話
“
CHAR
比VARCHAR
”好另一個 _old_wives 的故事。即使在 MyISAM 中,這句話也經常被斷章取義。
- 即使在上下文中它也很少有效
- 如果您有可變長度數據,則 I/O 的節省高於所謂的
CHAR
over節省VARCHAR
。- 在 InnoDB 中,
CHAR
大部分VARCHAR
實現是相同的。底線: 僅用於真正固定長度的字元串**。
CHAR
**需要優化小事的神話
我先從“答案”開始。
甚至在查看數據之前,還有其他任務。
- 接收查詢,可能通過 WAN。(最多毫秒。)
- 解析查詢中的標記。
- 找出查詢中命名的每一列正在使用哪個表。
- 打開表。
- 呼叫優化器來推斷執行查詢的最佳方式。這將涉及定位所有可能的索引,對錶進行探測以收集統計資訊等。
- 執行查詢。
在宏偉的計劃中,查找記錄的成本遠遠高於使用記錄所做的任何事情。(這是一個概括,不是絕對的。)
- 找到記錄——也許是通過索引,也許是“下一個”獲取的最後一條記錄。
- 獲取包含記錄的塊。這可能記憶體在緩衝池中,但可能需要從磁碟中獲取。所以,這一步可能是納秒,也可能是毫秒。
- 剖析塊以找到有問題的行。如果多個事務正在執行,這可能包括掃描“歷史列表”,並且需要參考“隔離模式”來確定行的哪個副本是“可見的”。
- 既然您有了行,就需要將列分開——即使存在字外邊界問題、字節掃描、
NULL
檢查、長度檢查(例如 forVARchar
等,我們說的是每列納秒。- “字節序”在這裡出現。MySQL 可以處理具有二進制兼容性的 big-endian 和 little-endian 硬體架構。這意味著對於某些依賴於硬體的情況,它必須交換字節才能將列值轉換為正確的“字節序”。
- 對列做一些事情。這可能只是原封不動地複制它;它可能正在應用一個函式(整理、求和、sqrt 等)。再次納秒。
現在,你的問題是什麼?哦,是的,你擔心最後一步的一小部分。
一般的
- 由於各種硬體、軟體和設計原因,字邊界不值得考慮。
- 對於大型表,I/O 是比固定長度和可變長度的事物更大的性能因素。
- MyISAM 中的固定長度幾乎沒有什麼優勢。當你不做
UPDATE
或DELETE
+時,大多數都會消失INSERT
。- 一行中的所有列都需要“固定”,否則它是“可變的”。
- InnoDB 可能從“固定”中獲得零收益。
- MyISAM 是在添加可變長度字元集(utf8 等)之前設計的。使用 utf8 時, Even
CHAR
的長度實際上是可變的。(並且停止閱讀任何超過十年的 MySQL 參考資料。)