Ich habe eine MYSQL InnoDB-Tabelletable
mit den folgenden Spalten (Tabellen- und Spaltennamen ge?ndert):
wobei rel_ab
是描述給定日期 2 個變量 var_a
和 var_b
之間關(guān)系的列。 (var_a
和 var_b
sich auf verschiedene Tabellen bezieht)
Daten werden jeden Tag stapelweise hochgeladen, insgesamt etwa 7 Millionen Zeilen pro Tag. Das Problem bestand darin, dass das Hochladen jedes neuen t?glichen Stapels bereits nach wenigen Wochen Stunden dauerte. Natürlich müssen wir unser Tischdesign verbessern. Hier finden Sie einige zus?tzliche Details zu unserem Formular.
COMPRESSION="zlib"
. var_a
和 var_b
.
的查詢 SELECT * FROM table WHERE date =
. Die Auswahl dauert nur wenige Minuten. var_a
和 var_b
verweist. df.to_sql('temp', con, if_exists='replace', index=False, method='multi')
hochgeladen, wobei wir ?ignorieren“ einfügen temp< /code> auf df.to_sql('temp', con, if_exists='replace', index=False, method='multi')
上傳,我們在其中插入忽略 < code>temp
到 table
,然后刪除 temp
, dann temp
l?schen. Also habe ich vor, mindestens eines der folgenden Dinge zu tun:
var_a
和 var_b
und verlassen Sie sich darauf, dass der Daten-Upload-Prozess alles richtig macht. Dies liegt daran, dass in unserem Anwendungsfall keiner der beiden Indizes die Abfragegeschwindigkeit tats?chlich verbessert. table_230501
的表,其中包含 var_a
、var_b
、rel_ab
. Dies liegt daran, dass wir jeweils nur ein Datum ausw?hlen. Ich wei?, dass die erste L?sung die Datenintegrit?t gef?hrden kann und die zweite L?sung unsere Architektur durcheinander bringen wird. Aufgrund meiner begrenzten Erfahrung habe ich auch noch nie von der zweiten Option geh?rt und kann online keine Beispiele für dieses Design finden. Sind diese Optionen eine sinnvolle L?sung? Beide erh?hen die Upload-Geschwindigkeit und reduzieren die Festplattennutzung, haben aber auch ihre Nachteile. Welche anderen M?glichkeiten gibt es sonst, die Upload-Geschwindigkeit zu erh?hen?
EDIT: Meins SHOW CREATE TABLE
sollte so aussehen
CREATE TABLE table ( date date NOT NULL, var_a int NOT NULL, var_b int NOT NULL, rel_ab decimal(19,16) NOT NULL, PRIMARY KEY (date,`var_a`,`var_b`), KEY a_idx (var_a), KEY b_idx (var_b), CONSTRAINT a FOREIGN KEY (var_a) REFERENCES other_table_a (var_a) ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT b FOREIGN KEY (var_b) REFERENCES other_table_b (var_b) ON DELETE RESTRICT ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMPRESSION="zlib"
有一些潛在的解決方案可以幫助您提高 MySQL 表的上傳速度:
刪除 var_a 和 var_b 上的索引:由于您沒有使用這些索引來加速查詢,因此刪除它們可以幫助加快上傳過程。但是,如果您使用外鍵約束,通常建議在屬于外鍵的列上保留索引。
按日期對表進行分區(qū):分區(qū)有助于提高查詢性能,因為它允許數(shù)據(jù)庫僅掃描給定查詢的相關(guān)分區(qū)。但是,它也會使維護和備份變得更加復雜,如果您的查詢已經(jīng)表現(xiàn)良好,則可能沒有必要。
使用批量插入方法:您可以嘗試使用批量插入方法,例如 LOAD DATA INFILE 或 MySQL 批量插入 API,而不是使用 df.to_sql 插入單獨的行。這比單獨插入要快,特別是如果您可以批量上傳數(shù)據(jù)而不是一次一行。
使用不同的壓縮算法:您當前正在使用 zlib 壓縮,但還有其他壓縮算法可能對您的數(shù)據(jù)更快或更有效。您可以嘗試嘗試不同的壓縮選項,看看它們是否可以提高上傳速度。
增加服務(wù)器資源:如果您有預(yù)算和資源,升級服務(wù)器硬件或增加服務(wù)器數(shù)量可能有助于提高上傳速度。這可能不是每個人都可行的選擇,但如果您已經(jīng)用盡其他選擇,則值得考慮。
就您建議的選項而言,刪除外鍵約束可能會導致數(shù)據(jù)完整性問題,因此我不推薦這種方法。如果您的查詢已經(jīng)遇到性能問題,則按日期分區(qū)可能是一個很好的解決方案,但如果您的查詢已經(jīng)快速運行,則可能沒有必要。
要加快上傳速度,請將其刪除。說真的,如果您所做的唯一一件事就是準確獲取某個日期文件中的內(nèi)容,為什么要將數(shù)據(jù)放入表中呢? (您的評論指出單個文件實際上是幾個文件。首先將它們組合起來可能是一個好主意。)
如果您確實需要表中的數(shù)據(jù),讓我們討論這些...
加載數(shù)據(jù)
?希望不是一次插入一行。我不知道熊貓是如何工作的。 (也不知道其他 99 個“簡化”MySQL 訪問的軟件包是如何工作的。)請了解它的幕后功能。您可能必須繞過 Pandas 才能獲得更好的性能。批量加載的速度至少是逐行加載的 10 倍。FLOAT
?MEDIUMINT [UNSIGNED]
每天至少可以節(jié)省 7MB。多個“相同”的表總是不明智的。一張桌子總是更好。但是,正如上面所建議的,零表仍然更好。