用於密集模式更改查詢 (DDL) 的 mysql 優化
在 CI 的上下文中,希望大規模並行化測試的執行。正在測試的程式碼需要存在數據庫,因此使用了 MySQL(正如應用程序現在使用的那樣)。
如果使用一個(大)數據庫伺服器並將測試案例分成例如 50 個 bin,每個 bin 轉到不同的執行器,則每個執行器將首先執行為該執行器設置專用模式的遷移。需要注意的一件事是,這些表在其短暫的生命週期內預計不會包含大量數據。
目的是盡可能快地優化測試執行時間,但目前,由於各種原因(一些不清楚,但與數據庫/查詢有關),時間不是很確定。
因此我的問題是:
- 如何針對這種大規模並行模式創建場景優化數據庫配置?例如,模式、表、索引等是否可以以較小的“大小”創建,這可能意味著所有這些創建/更改查詢的執行時間更快?
- 可以以某種方式優化查詢嗎?和/或更確切地說,是否可以從客戶端(具有管理員訪問權限)一開始就執行一些參數設置查詢,以正確的方式對其進行調整?
- 任何其他人能想到的策略?即使是可能對此更好的不同數據庫風格也是一個很好的建議,至少出於討論的目的 - 但這裡的策略可以與其他任何東西相關,而不僅僅是數據庫軟體或引擎
請參閱
pt-online-schema-change
,gh-ost
和具有更好“即時”的更新版本ALTER
。查詢優化是一個很大的話題。讓我們討論具體的查詢。使用 SlowLog查找“最差”的查詢。
MySQL 的預設配置實際上是最佳的。同樣,讓我們看看具體的查詢,看看是否有一些微妙的可調參數可能會有所幫助。
MySQL 幾乎沒有並行性。例如,您可以在不同的執行緒中同時載入多個表。同上獲取。這些事情阻止了很多並行性非常有用:
- 排序 –
DISTINCT
、GROUP BY
和ORDER BY
往往是瓶頸。- I/O——這往往是處理必須通過的單一渠道。縮小數據大小(8 字節
BIGINT
很少值得額外的大小。)- “複合”和/或“覆蓋”索引可以提供最佳的性能提升。
PARTITIONing
很少提供任何性能優勢。再次,讓我們看看具體情況。- 表的“大小”在性能方面確實很重要,但它取決於查詢和索引是否僅略大於 O(1)、O(log N)、O(N) 等。
- 不要手動將一個表拆分為多個子表;對於程式碼和性能而言,這幾乎總是一個壞主意。
您可以要求進行調整審查;這裡的說明:http: //mysql.rjweb.org/doc.php/mysql_analysis#tuning
另見“ShardQuery”——它在某些情況下很有用。
您可以使用MEMORY 儲存引擎來減輕 MySQL 伺服器寫入 DDL 和 DML 查詢的持久儲存的負擔。MEMORY 表只存在於 RAM 中,速度非常快,但數據易失,如果 MySQL Server 關閉,數據會失去。對於 CI 伺服器,這可能不是問題。
缺點是 MEMORY 儲存引擎可能與預設儲存引擎 InnoDB 有細微的行為差異。如果你有一個典型的 CRUD 風格的應用程序,這可能不會影響你,但是你沒有描述任何關於你的表或查詢的具體內容,所以你只需要嘗試它並註意意外行為。
我不建議在 CI 中為您的數據庫使用不同的軟體產品。最好使用相同品牌、相同版本和盡可能接近最終將用於部署的相同配置選項進行測試。我建議使用 MEMORY 引擎而不是 ACID 儲存引擎(例如 InnoDB)進行測試,但我只能妥協。
創建表和索引等通常會創建空表,因此您無法做很多事情來使各個 DDL 語句更快。如果您在測試設置中載入這些帶有數據的表,則從您的描述中不清楚。你能用更少的數據來測試嗎?
我見過的另一種策略是使用 LVM 文件系統快照來快速恢復到數據和元數據的初始狀態。如果載入大量測試數據的時間是瓶頸,這將更有幫助。由於您說這些表沒有很多數據,因此使用 LVM 快照可能沒有多大好處。