AWS RDS MySQL 隨著時間的推移速度變慢

AWS RDS MySQL 隨著時間的推移速度變慢

我讀過很多關於這個主題的文章,但沒有一篇討論 AWS RDS MySQL 資料庫。自三天前以來,我在 AWS EC2 執行個體中執行 python 腳本,該腳本在我的 AWS RDS MySQL 資料庫中寫入資料列。我必須寫入 3500 萬行,所以我知道這需要一些時間。我定期檢查資料庫的效能,三天後(今天)我意識到資料庫正在變慢。當它開始時,前 100,000 行僅在 7 分鐘內寫入(這是我正在處理的行的範例)

0000002178-14-000056    AccountsPayableCurrent  us-gaap/2014        20131231    0   USD 266099000.0000

三天后,資料庫中已寫入 5,385,662 行,但現在寫入 100,000 行需要近 3 個小時。怎麼了?

我運行的 EC2 執行個體是 t2.small。如果需要,您可以在這裡查看規格:EC2 規格 。我運行的 RDS 資料庫是 db.t2.small。請在此處查看規格:RDS 規格

我將在此處附上一些有關資料庫和 EC2 執行個體效能的圖表: 資料庫CPU/資料庫記憶體/資料庫寫入 IOPS/資料庫寫入吞吐量/ EC2 網路(位元組)/EC2 網路輸出(位元組)

如果你能幫助我那就太好了。多謝。

編輯 1:我如何插入行? 正如我之前所說,我有一個在 EC2 執行個體上運行的 python 腳本,該腳本讀取文字文件,使用這些值進行一些計算,然後將每個「新」行寫入資料庫。這是我的一小段程式碼。 我如何讀取文字檔?

for i in path_list:
  notify("Uploading: " + i)
  num_path = "path/" + i + "/file.txt"
  sub_path = "path/" + i + "/file.txt"

  try:
    sub_dict = {}
    with open(sub_path) as sub_file:
      for line in sub_file:
        line = line.strip().split("\t")
        sub_dict[line[0]] = line[1] # Save cik for every accession number
        sub_dict[line[1] + "-report"] = line[25] # Save report type for every CIK
        sub_dict[line[1] + "-frecuency"] = line[28] # Save frecuency for every CIK

    with open(num_path) as num_file:
      for line in num_file:
        num_row = line.strip().split("\t")

        # Reminder: sometimes in the very old reports, cik and accession number does not match. For this reason I have to write 
        # the following statement. To save the real cik.

        try: 
          cik = sub_dict[num_row[0]]
        except:
          cik = num_row[0][0:10]

        try: # If there is no value, pass
          value = num_row[7]
          values_dict = {
                  'cik': cik, 
                  'accession': num_row[0][10::].replace("-", ""),  
                  'tag': num_row[1], 
                  'value': value, 
                  'valueid': num_row[6], 
                  'date': num_row[4]
                  }

          sql = ("INSERT INTO table name (id, tag, value_num, value_id, endtime, cik, report, period) "
              "VALUES ('{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}')".format(
                  values_dict['cik'] + values_dict['accession'] + values_dict['date'] + values_dict['value'].split(".")[0] + "-" + values_dict['tag'], 
                  values_dict['tag'], 
                  float(values_dict['value']), 
                  values_dict['valueid'], 
                  values_dict['date'], 
                  int(values_dict['cik']), 
                  sub_dict[values_dict['cik'] + "-report"], 
                  sub_dict[values_dict['cik'] + "-frecuency"]
                  ))

          cursor.execute(sql)
          connection.commit()

我知道沒有什麼except:可以表達try的,但這只是腳本的一部分。我認為重要的部分是如何插入每一行。如果我不需要對值進行計算,我將使用Load Data Infile將文字檔案寫入資料庫。我只是意識到commit每次插入一行時這也許不是一個好主意。我將嘗試在 10,000 行左右之後提交。

答案1

T2 和 T3 實例(包括 db.t2 db.t3 實例)使用CPU積分系統。當實例空閒時,它會累積 CPU 積分,然後可以使用這些積分在短時間內運行得更快 -爆發性能。一旦你耗盡了積分,它就會減慢到基線性能

一種選擇是啟用T2/T3 無限在您的 RDS 配置中進行設置,這將使實例在需要時全速運行,但您將支付所需的額外積分。

另一個選項是將實例類型變更為 db.m5 或支援一致性能的其他非 T2/T3 類型。

這裡有一個更深入的CPU積分的解釋以及如何累積和花費:關於明確t2和t3的工作條件?

希望有幫助:)

答案2

  • 單行的速度INSERTs比 100 行慢 10INSERTsLOAD DATA

  • UUID 很慢,尤其是當表格變大時。

  • UNIQUE需要檢查索引整理一個iNSERT.

  • 非唯一INDEXes可以在背景完成,但它們仍然需要一些負載。

請提供SHOW CREATE TABLE以及使用的方法INSERTing。可能還有更多提示。

答案3

每次提交事務時,索引都需要更新。更新索引的複雜度與表中的行數有關,因此隨著行數的增加,索引更新會逐漸變慢。

假設您使用 InnoDB 表,您可以執行下列操作:

SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET AUTOCOMMIT = 0;
ALTER TABLE table_name DISABLE KEYS;

然後進行插入,但對它們進行批次處理,以便一條語句插入(例如)幾十行。喜歡INSERT INTO table_name VALUES ((<row1 data>), (<row2 data>), ...)。當插入完成後,

ALTER TABLE table_name ENABLE KEYS;
SET UNIQUE_CHECKS = 1;
SET FOREIGN_KEY_CHECKS = 1;
COMMIT;

您可以根據自己的情況進行調整,例如,如果行數很大,那麼您可能想要插入 50 萬行,然後提交。這假設您在執行插入時資料庫不是「活動的」(即使用者主動讀取/寫入資料庫),因為您停用了輸入資料時可能依賴的檢查。

相關內容