[TIL]Elasticsearch 구축용 csv 파일 로딩 속도 비교

차보경·2023년 1월 5일
2

TIL

목록 보기
22/37

상황

이번 Elasticsearch 사용시 JSON 형변환 없이 bulk()를 사용해서 데이터를 넣기로 하였다.

csv file 에서 data를 로드해올 때 어떤 방법이 가장 빠를 것인지 확인하기 위해서 여러 방법으로 실험해 보았다.

1. reader = csv.DictReader(f) 후 doc 직접 작성

  • 가장 빠를 것으로 생각되지만 doc 안에 내용을 일일이 작성해서 넣어줘야하기 때문에 조큼... 귀찮았다.....(멋쓱)
  • 그리고 나중에 column이 바뀐다면 또 맞춰서 바꿔줘야하는 하드코딩이라 유지보수 부분에서 오류날 가능성이 클 것으로 예상됨(어디까지나 초보의 생각...^-^)

2. pd.read_csv 후 data.iterrows() 사용, doc 직접 작성

  • csv 로드시 open보다 pandas가 더 빠르다는 블로그를 보고 정말일까 확인하기 위한 테스트!
  • 이것도 하드코딩이라 나중에 오류날 가능성이 클 것으로 예상됨(어디까지나 초보의 생각...^-^)

3. pd.read_csv 후 data.iterrows() 사용 doc 내용 for문으로 채움

  • 긴 코드가 짧아져서 나름 뿌듯한 코드(숏코딩보단 가독성이 더 좋긴한데,, 뿌듯하자냐,,,)
  • 그리고 csv의 col 변경시 자동으로 적용되어 유지보수에 좋음!

이 3가지를 가지고 시도했다.

TEST CODE

def generate_actions():
    """Reads the file through csv.DictReader() and for each row
    yields a single document. This function is passed into the bulk()
    helper to create many documents in sequence.
    """
    ############################### with open #################################
    start_time = time.time()
    with open(DATASET_PATH, mode="r",encoding="utf-8-sig") as f:
        reader = csv.DictReader(f)

        for idx, row in enumerate(reader):
            doc = {
                "_id": idx,
                "TITLE" : row["TITLE"],
                "URL" : row["URL"],
                "DESCRIPTION" : row["DESCRIPTION"],
                "DURATION" : row["DURATION"],
                "PUBLISHED" : row["PUBLISHED"],
                "VIEWS" : row["VIEWS"],
                "LIKES" : row["LIKES"],
                "TAGS" : row["TAGS"],
                "CATEGORY" : row["CATEGORY"],
                "CHANNEL" : row["CHANNEL"],
                "TEXTS" : row["TEXTS"],
                "HASHTAGS" : row["HASHTAGS"],
                "USE_TEXTS" : row["USE_TEXTS"],
                "GENSIM" : row["GENSIM"],
                "KEYBERT" : row["KEYBERT"],
                "AFTER_REMOVE_ADVERB" : row["AFTER_REMOVE_ADVERB"]
            }
    end_time = time.time()
    print(f"Hard coding data done. time taken ===> {end_time - start_time:.5f}sec")
    
    ################################ pd.read_csv + 하드코딩 ################################
    start_time = time.time()
    data = pd.read_csv("221219_extract_file.csv")
    for idx, row in data.iterrows():
        doc = {
                "_id": idx,
                "TITLE" : row["TITLE"],
                "URL" : row["URL"],
                "DESCRIPTION" : row["DESCRIPTION"],
                "DURATION" : row["DURATION"],
                "PUBLISHED" : row["PUBLISHED"],
                "VIEWS" : row["VIEWS"],
                "LIKES" : row["LIKES"],
                "TAGS" : row["TAGS"],
                "CATEGORY" : row["CATEGORY"],
                "CHANNEL" : row["CHANNEL"],
                "TEXTS" : row["TEXTS"],
                "HASHTAGS" : row["HASHTAGS"],
                "USE_TEXTS" : row["USE_TEXTS"],
                "GENSIM" : row["GENSIM"],
                "KEYBERT" : row["KEYBERT"],
                "AFTER_REMOVE_ADVERB" : row["AFTER_REMOVE_ADVERB"]
            }
    end_time = time.time()
    print(f"pandas data done. time taken ===> {end_time - start_time:.5f}sec")
    
    ############################### pd.read for문으로 #################################
    start_time = time.time()
    data = pd.read_csv("221219_extract_file.csv")
    colunms = [col for col in data]

    for idx, row in data.iterrows():

        # 1행 doc생성
        row_list = []
        for i in range(len(colunms)):
            row_data = [colunms[i], row[i]]
            row_list.append(row_data)

        doc = {
                "_index": "youtube_data",
                "_id": idx,
                "_source": dict(row_list) # 각 행 dictionary 추가함
                }
    end_time = time.time()
    print(f"for문 data done. time taken ===> {end_time - start_time:.5f}sec")

결과 비교

Hard coding data done. time taken ===> 0.01341sec (최대 0.01407sec)
pandas data done. time taken      ===> 0.04363sec (최대 0.05037sec)
for문 data done. time taken       ===> 0.03245sec (최대 0.05023sec)

👍1번 case 압승👍

1의 경우 최소 0.00611sec 까지 나오는 것을 보고 그냥 이렇게 가야겠다 싶었다^_^,,,,

그리고 생각보다 open보다 pandas csv가 더 느린게 좀 의외였다. 데이터 수가 적어서 그런가? (현재 사용량 130개)

나중에 실제 데이터(약 1억개)가 들어오면 다시 테스트를 해봐야겠다.

그리고 for문으로 작성한게 하드코딩한것보다 빠르게 나온게 또 의외고...(최대시간 비교하면 비슷하긴 하지만)
나중에 유지보수를 위해서는 for문이 더 좋을 것 같긴 한데,,, 뭐 컬럼이 자주 바뀌는 내용도 아니니까 우선은 속도적인 면을 위해서 1번으로 가는게 좋다는 생각이다. (어짜피 mapping하면서 이미 적었으니ㄲㅏ....ㅎ....)

속도 테스트는 이걸로 끝.........!

profile
차보의 Data Engineer 도전기♥ (근데 기록을 곁들인)

0개의 댓글