이 주제에 대한 많은 게시물을 읽었지만 그 중 AWS RDS MySQL 데이터베이스에 관한 게시물은 없습니다. 3일 전부터 AWS RDS MySQL 데이터베이스에 행을 쓰는 AWS EC2 인스턴스에서 Python 스크립트를 실행하고 있습니다. 3,500만 행을 작성해야 하므로 시간이 좀 걸릴 것이라는 것을 알고 있습니다. 주기적으로 데이터베이스 성능을 확인했는데, 3일 후(오늘) 데이터베이스 속도가 느려지고 있다는 사실을 깨달았습니다. 시작했을 때 처음 100,000개의 행이 단 7분 만에 작성되었습니다(이것은 제가 작업 중인 행의 예입니다).
0000002178-14-000056 AccountsPayableCurrent us-gaap/2014 20131231 0 USD 266099000.0000
3일 후에는 5,385,662개의 행이 데이터베이스에 기록되었지만 지금은 100,000개의 행을 작성하는 데 거의 3시간이 걸립니다. 무슨 일이 일어나고 있나요?
제가 실행 중인 EC2 인스턴스는 t2.small입니다. 필요한 경우 여기에서 사양을 확인할 수 있습니다.EC2 사양 . 제가 실행 중인 RDS 데이터베이스는 db.t2.small입니다. 여기에서 사양을 확인하세요.RDS 사양
여기에 데이터베이스와 EC2 인스턴스의 성능에 대한 몇 가지 차트를 첨부하겠습니다. DB CPU/DB 메모리/DB 쓰기 IOPS/DB 쓰기 처리량/ 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행INSERTs
또는LOAD 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만 개를 삽입한 다음 커밋할 수 있습니다. 이는 삽입을 수행하는 동안 데이터베이스가 '실시간'(즉, 사용자가 적극적으로 읽고 쓰는 중)이 아니라고 가정합니다. 왜냐하면 데이터베이스가 데이터를 입력할 때 의존할 수 있는 검사를 비활성화하고 있기 때문입니다.