MyISAM과 InnoDB의 비교
데이터베이스 쓰기가 많은 프로젝트를 진행하고 있습니다(70%의 삽입과 30%의 읽기).이 비율에는 1개의 읽기 및 쓰기라고 생각되는 업데이트도 포함됩니다.판독치가 더러워질 수 있습니다(읽을 때 100% 정확한 정보는 필요 없습니다).
해당 작업은 한 시간에 100만 건 이상의 데이터베이스 트랜잭션을 수행합니다.
MyISAM과 InnoDB의 차이점에 대해 웹에서 많은 정보를 읽었는데, MyISAM은 이 작업에 사용할 특정 데이터베이스/테이블에 대해 매우 확실한 선택인 것 같습니다.제가 본 바로는 행 레벨 잠금 기능이 지원되므로 거래가 필요한 경우 InnoDB가 좋다고 생각합니다.
이런 종류의 부하(또는 그 이상)를 경험한 사람이 있습니까?MyISAM이 좋은가요?
InnoDB와 MyISAM 중 어느 쪽을 선택할지 결론을 내릴 수 있도록 표에서 이 질문에 대해 간단히 논의했습니다.
다음은 어떤 상황에서 어떤 DB 스토리지 엔진을 사용해야 하는지에 대한 간단한 개요입니다.
MyISAM InnoDB----------------------------------------------------------------필요한 전문 검색 Yes 5.6.4 ----------------------------------------------------------------트랜잭션 필요 Yes----------------------------------------------------------------자주 선택되는 쿼리 예----------------------------------------------------------------빈번한 삽입, 업데이트, 삭제 예----------------------------------------------------------------행 잠금(단일 테이블에서의 다중 처리)네.----------------------------------------------------------------관계 기반 설계 있음
요약
- 거의 모든 상황에서 InnoDB가 최선의 선택입니다.
- 단, 자주 읽고 거의 쓰지 않으면 MyISAM을 사용합니다.
- MySQL <= 5.5에서 전체 텍스트 검색, MyISAM 사용
저는 데이터베이스 전문가도 아니고 경험상 말하는 것도 아닙니다.단,
MyISAM 테이블은 테이블레벨 잠금을 사용합니다.트래픽 추정치에 따르면 초당 거의 200회의 쓰기가 가능합니다.MyISAM에서는 이들 중1개만 동시에 진행할 수 있습니다.오버런을 피하기 위해 하드웨어가 이러한 트랜잭션에 대응할 수 있는지 확인해야 합니다.즉, 1개의 쿼리에 걸리는 시간은 5ms를 넘지 않습니다.
따라서 행 레벨 잠금을 지원하는 스토리지 엔진(예: InnoDB)이 필요합니다.
한편, 간단한 스크립트를 몇 개 작성하여 각 스토리지 엔진과 로드를 시뮬레이션한 후 결과를 비교하는 것은 매우 간단해야 합니다.
성능, 읽기 vs. 쓰기, 외부 키 등에 대해 자주 이야기하지만, 스토리지 엔진에는 또 하나의 필수 기능인 원자 업데이트 기능이 있다고 생각합니다.
이것을 시험해 보세요.
- 5초 걸리는 MyISAM 테이블에 대해 UPDATE를 발행합니다.
- 업데이트 진행 중(예: 2.5초 후) Ctrl+C를 눌러 중단합니다.
- 테이블에서 효과를 관찰합니다.몇 개의 행이 업데이트되었습니까?갱신되지 않은 것은 몇 개입니까?표를 읽을 수 있습니까, 아니면 Ctrl+C 키를 눌렀을 때 테이블이 망가졌습니까?
- InnoDB 테이블에 대해 UPDATE를 사용한 동일한 실험을 시도하여 진행 중인 쿼리를 중단합니다.
- InnoDB 표를 확인합니다.행이 0개 업데이트되었습니다.InnoDB는 당신에게 원자적인 업데이트가 있음을 보증하며, 만약 완전한 업데이트를 커밋할 수 없다면 모든 변경을 롤백합니다.또한 테이블은 파손되지 않았습니다.이것은, 를 사용해도 동작합니다.
killall -9 mysqld
충돌 시뮬레이션을 합니다.
퍼포먼스는 물론 바람직하지만 데이터를 잃지 않는 것이 우선입니다.
MySQL을 사용하여 대용량 시스템을 작업하고 MyISAM과 InnoDB를 모두 사용해 보았습니다.
MyISAM의 테이블 레벨 잠금으로 인해 워크로드에 심각한 성능 문제가 발생했으며, 이는 귀사와 비슷한 소리입니다.아쉽게도 InnoDB에서의 퍼포먼스도 기대했던 것보다 나빴습니다.
결국 데이터를 fragment화함으로써 경합 문제를 해결했습니다.이것에 의해, 「핫」테이블에 삽입되어 「핫」테이블에 쿼리가 행해지지 않는다」를 선택합니다.
이를 통해 "stale" 테이블에서 삭제(데이터는 시간에 민감하고 X일치만 보유)가 발생했지만 선택 쿼리에 의해 다시 처리되지 않았습니다.InnoDB는 대량 삭제 시 성능이 떨어지는 것 같습니다. 따라서 데이터를 삭제할 계획이라면 오래된 데이터를 삭제하지 않고 폐기할 수 있는 오래된 테이블에 저장하도록 구성할 수 있습니다.
물론 어떤 어플리케이션인지 모르겠지만 MyISAM과 InnoDB의 몇 가지 문제에 대한 이해를 얻을 수 있기를 바랍니다.
경기 시작 시간이 좀 늦었네요.MYISAM과 InnoDB의 주요 차이점에 대해 몇 달 전에 쓴 꽤 포괄적인 글이 있습니다.컵파(그리고 비스킷)를 들고 즐기세요.
MyISAM과 InnoDB의 주요 차이점은 참조 무결성 및 트랜잭션입니다.잠금, 롤백 및 전체 텍스트 검색과 같은 다른 차이점도 있습니다.
참조 무결성
참조 무결성에 의해 테이블 간의 관계가 일관되게 유지됩니다.보다 구체적으로 말하면, 테이블(예: 목록)에 다른 테이블(예: 제품)을 가리키는 외부 키(예: 제품 ID)가 있는 경우, 포인트 투 테이블이 업데이트 또는 삭제되면 이러한 변경 내용이 링크 테이블에 캐스케이드됩니다.이 예에서는 제품 이름을 변경하면 링크 테이블의 외부 키도 업데이트됩니다. '제품' 테이블에서 제품을 삭제하면 삭제된 항목을 가리키는 목록도 모두 삭제됩니다.또한 새로운 목록에는 유효한 기존 엔트리를 가리키는 외부 키가 있어야 합니다.
InnoDB는 Relational DBMS(RDBMS)이므로 참조 무결성이 있지만 MyISAM은 그렇지 않습니다.
트랜잭션 및 원자성
테이블의 데이터는 SELECT, INSERT, UPDATE 및 DELETE와 같은 DML(Data Manipulation Language) 문을 사용하여 관리됩니다.트랜잭션 그룹 2개 이상의 DML 스테이트먼트를 하나의 작업 단위로 정리하여 전체 유닛이 적용되거나 적용되지 않거나 둘 다 적용되지 않습니다.
MyISAM은 트랜잭션을 지원하지 않지만 InnoDB는 지원합니다.
MyISAM 테이블 사용 중 조작이 중단되면 조작은 즉시 중단되며 조작이 완료되지 않은 경우에도 영향을 받는 행(또는 각 행 내의 데이터)은 영향을 받습니다.
InnoDB 테이블 사용 중 조작이 중단되면 원자성을 가진 트랜잭션을 사용하기 때문에 완료되지 않은 트랜잭션은 커밋되지 않으므로 활성화되지 않습니다.
테이블 잠금과 행 잠금
쿼리가 MyISAM 테이블에 대해 실행되면 쿼리가 있는 테이블 전체가 잠깁니다.즉, 후속 쿼리는 현재 쿼리가 완료된 후에만 실행됩니다.큰 테이블을 읽고 있거나 읽기 및 쓰기 작업이 자주 수행되면 쿼리의 대량 백로그가 발생할 수 있습니다.
InnoDB 테이블에 대해 쿼리를 실행하면 관련된 행만 잠기고 나머지 테이블은 CRUD 작업에 사용할 수 있습니다.즉, 쿼리는 같은 행을 사용하지 않는 한 같은 테이블에서 동시에 실행할 수 있습니다.
InnoDB의 이 기능은 동시성으로 알려져 있습니다.동시성이 뛰어난 만큼 커널 스레드 간 전환에 오버헤드가 있다는 점에서 일부 테이블 범위에 적용되는 주요 단점이 있습니다.서버가 정지하지 않도록 커널 스레드에 제한을 설정해야 합니다.
트랜잭션 및 롤백
MyISAM에서 작업을 실행하면 변경사항이 설정되고 InnoDB에서는 변경사항이 롤백될 수 있습니다.트랜잭션을 제어하기 위해 사용되는 가장 일반적인 명령어는 COMMIT, ROLLBACK 및 SAVEPOINT입니다. 1. COMMIT - 여러 DML 작업을 쓸 수 있지만 변경 내용은 COMMIT가 이루어진 경우에만 저장됩니다.2. ROLLBK - 아직 커밋되지 않은 작업은 폐기할 수 있습니다.SAVEPOINT - 롤백 조작을 롤백할 수 있는 조작 목록의 포인트를 설정합니다.
신뢰성.
MyISAM은 데이터 무결성을 제공하지 않습니다.하드웨어 장애, 부정 셧다운 및 취소된 조작으로 인해 데이터가 파손될 수 있습니다.이를 위해서는 인덱스와 테이블을 완전히 복구하거나 재구축해야 합니다.
반면 InnoDB는 트랜잭션 로그, 이중 쓰기 버퍼, 자동 체크섬 및 검증을 사용하여 손상을 방지합니다.InnoDB는 변경하기 전에 트랜잭션 전 데이터를 ibdata1이라는 시스템 테이블스페이스 파일에 기록합니다.크래시가 발생하면 InnoDB는 이러한 로그의 재생을 통해 자동 복구합니다.
FULLTEXT 인덱싱
InnoDB는 MySQL 버전 5.6.4까지 FULLTEXT 인덱싱을 지원하지 않습니다.이 게시물의 작성 시점에서는 많은 공유 호스팅 프로바이더의 MySQL 버전이 5.6.4 이하이며, 이는 InnoDB 테이블에서 FULLTEXT 인덱싱을 지원하지 않음을 의미합니다.
단, 이는 MyISAM을 사용하는 타당한 이유가 아닙니다.최신 버전의 MySQL을 지원하는 호스팅 공급자로 변경하는 것이 좋습니다.FULLTEXT 인덱싱을 사용하는 MyISAM 테이블을 InnoDB 테이블로 변환할 수 없습니다.
결론
결론적으로 InnoDB는 기본 스토리지 엔진이 되어야 합니다.MyISAM 또는 기타 데이터 유형이 특정 요구에 부합하는 경우 선택합니다.
쓰기 및 읽기가 많은 로드는 InnoDB의 이점을 누릴 수 있습니다. 기능을 하므로 InnoDB는 테이블잠금이 아닌 행잠금 기능을 합니다.SELECT
뿐만 , 다수의 ,, 로, 서, 은, 은, 은, 많, 많, 많, 많, can, can, can, can, can, can, can, can, can, can, can, can, can, can, can, can, can, can, can, INSERT
s. 단, SQL 트랜잭션을 사용하는 경우를 제외하고 InnoDB 커밋 플러시를 2(innodb_flush_log_at_trx_commit)로 설정합니다.이로 인해 MyISAM에서 InnoDB로 테이블을 이동할 때 손실되는 많은 원시 성능을 얻을 수 있습니다.
또, 레플리케이션의 추가도 검토해 주세요.따라서 읽기 확장이 가능해지고 읽기가 최신일 필요가 없다고 했으므로 복제가 다소 늦어질 수 있습니다.트래픽이 가장 많은 곳 이외에는 어떤 곳에서도 따라잡을 수 있는지 확인하세요.그렇지 않으면 항상 뒤처져 결코 따라잡을 수 없습니다.단, 이 방법을 사용할 경우 슬레이브에서 읽기와 복제 지연 관리를 데이터베이스 핸들러로 분리할 것을 강력히 권장합니다.어플리케이션 코드가 이것을 모르는 것이 훨씬 더 간단하다.
마지막으로 테이블 부하에 주의해 주십시오.모든 테이블에서 읽기/쓰기 비율이 동일하지는 않습니다.읽기가 거의 100%인 일부 작은 테이블은 MyISAM을 유지할 수 있습니다.기입률이 에, 「100%」의 수.INSERT DELAYED
, 이는 「MyISAM」)에서만DELAYED
InnoDB 。
하지만 확실한 벤치마크입니다.
여기에 두 엔진 간의 기계적 차이를 다루는 다양한 응답 옵션을 추가하기 위해 경험적 속도 비교 연구를 제시합니다.
순수 속도면에서는 MyISAM이 InnoDB보다 빠르다고는 할 수 없지만, 제 경험상 PURE READ 작업 환경에서는 2.0~2.5배 정도 빠른 경향이 있습니다.분명히 이것은 모든 환경에 적합한 것은 아닙니다.다른 사람들이 쓴 것처럼 MyISAM에는 트랜잭션이나 외부 키 등의 기능이 없습니다.
아래 벤치마킹에서는 python을 사용하여 루프를 수행하고 timeit 라이브러리를 사용하여 타이밍을 비교했습니다.참고로 메모리 엔진도 포함했습니다.이것은 작은 테이블에만 적합하지만 전반적으로 최고의 퍼포먼스를 발휘합니다(계속 볼 수 있습니다).The table 'tbl' is full
MySQL 메모리 제한을 초과한 경우)다음 4가지 선택 유형을 살펴봅니다.
- 바닐라 셀렉트
- 카운트
- 조건부 선택
- 색인화 및 비색인화 서브클라이언트
먼저 다음 SQL을 사용하여 3개의 테이블을 만들었습니다.
CREATE TABLE
data_interrogation.test_table_myisam
(
index_col BIGINT NOT NULL AUTO_INCREMENT,
value1 DOUBLE,
value2 DOUBLE,
value3 DOUBLE,
value4 DOUBLE,
PRIMARY KEY (index_col)
)
ENGINE=MyISAM DEFAULT CHARSET=utf8
'My'와 함께ISAM은 두 번째와 세 번째 표에서 'InnoDB'와 'memory'를 대체했다.
1) 바닐라 셀렉트
★★★★★★★SELECT * FROM tbl WHERE index_col = xx
결과: 그리기
이러한 속도는 모두 거의 동일하며, 예상대로 선택할 열의 수는 선형입니다.InnoDB는 MyISAM보다 조금 빠른 것 같지만 이것은 매우 미미한 수준입니다.
코드:
import timeit
import MySQLdb
import MySQLdb.cursors
import random
from random import randint
db = MySQLdb.connect(host="...", user="...", passwd="...", db="...", cursorclass=MySQLdb.cursors.DictCursor)
cur = db.cursor()
lengthOfTable = 100000
# Fill up the tables with random data
for x in xrange(lengthOfTable):
rand1 = random.random()
rand2 = random.random()
rand3 = random.random()
rand4 = random.random()
insertString = "INSERT INTO test_table_innodb (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
insertString2 = "INSERT INTO test_table_myisam (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
insertString3 = "INSERT INTO test_table_memory (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
cur.execute(insertString)
cur.execute(insertString2)
cur.execute(insertString3)
db.commit()
# Define a function to pull a certain number of records from these tables
def selectRandomRecords(testTable,numberOfRecords):
for x in xrange(numberOfRecords):
rand1 = randint(0,lengthOfTable)
selectString = "SELECT * FROM " + testTable + " WHERE index_col = " + str(rand1)
cur.execute(selectString)
setupString = "from __main__ import selectRandomRecords"
# Test time taken using timeit
myisam_times = []
innodb_times = []
memory_times = []
for theLength in [3,10,30,100,300,1000,3000,10000]:
innodb_times.append( timeit.timeit('selectRandomRecords("test_table_innodb",' + str(theLength) + ')', number=100, setup=setupString) )
myisam_times.append( timeit.timeit('selectRandomRecords("test_table_myisam",' + str(theLength) + ')', number=100, setup=setupString) )
memory_times.append( timeit.timeit('selectRandomRecords("test_table_memory",' + str(theLength) + ')', number=100, setup=setupString) )
2) 카운트
★★★★★★★SELECT count(*) FROM tbl
결과: MyISAM이 승리
이는 MyISAM과 InnoDB의 큰 차이를 보여줍니다.MyISAM(및 메모리)은 테이블 내의 레코드 수를 추적하기 때문에 이 트랜잭션은 빠르고 O(1)입니다.InnoDB가 카운트하는 데 필요한 시간은 제가 조사한 범위 내의 테이블 크기에 따라 초선형적으로 증가합니다.MyISAM 쿼리에서 실제로 관찰된 속도 향상은 대부분 유사한 효과에 기인한 것으로 추측됩니다.
코드:
myisam_times = []
innodb_times = []
memory_times = []
# Define a function to count the records
def countRecords(testTable):
selectString = "SELECT count(*) FROM " + testTable
cur.execute(selectString)
setupString = "from __main__ import countRecords"
# Truncate the tables and re-fill with a set amount of data
for theLength in [3,10,30,100,300,1000,3000,10000,30000,100000]:
truncateString = "TRUNCATE test_table_innodb"
truncateString2 = "TRUNCATE test_table_myisam"
truncateString3 = "TRUNCATE test_table_memory"
cur.execute(truncateString)
cur.execute(truncateString2)
cur.execute(truncateString3)
for x in xrange(theLength):
rand1 = random.random()
rand2 = random.random()
rand3 = random.random()
rand4 = random.random()
insertString = "INSERT INTO test_table_innodb (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
insertString2 = "INSERT INTO test_table_myisam (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
insertString3 = "INSERT INTO test_table_memory (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
cur.execute(insertString)
cur.execute(insertString2)
cur.execute(insertString3)
db.commit()
# Count and time the query
innodb_times.append( timeit.timeit('countRecords("test_table_innodb")', number=100, setup=setupString) )
myisam_times.append( timeit.timeit('countRecords("test_table_myisam")', number=100, setup=setupString) )
memory_times.append( timeit.timeit('countRecords("test_table_memory")', number=100, setup=setupString) )
3) 조건부 선택
★★★★★★★SELECT * FROM tbl WHERE value1<0.5 AND value2<0.5 AND value3<0.5 AND value4<0.5
결과: MyISAM이 승리
여기서 MyISAM과 메모리는 거의 같은 성능을 발휘하며, 큰 테이블에서는 InnoDB를 약 50% 앞섭니다.이것은 MyISAM의 이점이 최대화되는 것 같은 질문입니다.
코드:
myisam_times = []
innodb_times = []
memory_times = []
# Define a function to perform conditional selects
def conditionalSelect(testTable):
selectString = "SELECT * FROM " + testTable + " WHERE value1 < 0.5 AND value2 < 0.5 AND value3 < 0.5 AND value4 < 0.5"
cur.execute(selectString)
setupString = "from __main__ import conditionalSelect"
# Truncate the tables and re-fill with a set amount of data
for theLength in [3,10,30,100,300,1000,3000,10000,30000,100000]:
truncateString = "TRUNCATE test_table_innodb"
truncateString2 = "TRUNCATE test_table_myisam"
truncateString3 = "TRUNCATE test_table_memory"
cur.execute(truncateString)
cur.execute(truncateString2)
cur.execute(truncateString3)
for x in xrange(theLength):
rand1 = random.random()
rand2 = random.random()
rand3 = random.random()
rand4 = random.random()
insertString = "INSERT INTO test_table_innodb (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
insertString2 = "INSERT INTO test_table_myisam (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
insertString3 = "INSERT INTO test_table_memory (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
cur.execute(insertString)
cur.execute(insertString2)
cur.execute(insertString3)
db.commit()
# Count and time the query
innodb_times.append( timeit.timeit('conditionalSelect("test_table_innodb")', number=100, setup=setupString) )
myisam_times.append( timeit.timeit('conditionalSelect("test_table_myisam")', number=100, setup=setupString) )
memory_times.append( timeit.timeit('conditionalSelect("test_table_memory")', number=100, setup=setupString) )
4) 서브셀렉트
결과: InnoDB가 승리
이 쿼리를 위해 하위 선택 항목에 대한 추가 테이블 세트를 만들었습니다.각 열은 기본 키 인덱스가 있는 열과 인덱스가 없는 열로 구성되어 있습니다.테이블 사이즈가 커서 메모리 엔진을 테스트하지 않았습니다.SQL 테이블 생성 명령어는
CREATE TABLE
subselect_myisam
(
index_col bigint NOT NULL,
non_index_col bigint,
PRIMARY KEY (index_col)
)
ENGINE=MyISAM DEFAULT CHARSET=utf8;
다시 한 번 '나의'ISAM'은 두 번째 표에서 InnoDB 대신 사용됩니다.
이 쿼리에서는 선택 테이블의 크기를 1000000으로 유지하고 대신 하위 선택 열의 크기를 변경합니다.
여기서 InnoDB는 쉽게 승리합니다.적당한 크기의 표를 확인한 후 두 엔진의 크기가 하위 선택 항목의 크기에 따라 선형적으로 조정됩니다.인덱스는 MyISAM 명령어 속도를 높이지만 InnoDB 속도에는 거의 영향을 미치지 않습니다.subSelect.png
코드:
myisam_times = []
innodb_times = []
myisam_times_2 = []
innodb_times_2 = []
def subSelectRecordsIndexed(testTable,testSubSelect):
selectString = "SELECT * FROM " + testTable + " WHERE index_col in ( SELECT index_col FROM " + testSubSelect + " )"
cur.execute(selectString)
setupString = "from __main__ import subSelectRecordsIndexed"
def subSelectRecordsNotIndexed(testTable,testSubSelect):
selectString = "SELECT * FROM " + testTable + " WHERE index_col in ( SELECT non_index_col FROM " + testSubSelect + " )"
cur.execute(selectString)
setupString2 = "from __main__ import subSelectRecordsNotIndexed"
# Truncate the old tables, and re-fill with 1000000 records
truncateString = "TRUNCATE test_table_innodb"
truncateString2 = "TRUNCATE test_table_myisam"
cur.execute(truncateString)
cur.execute(truncateString2)
lengthOfTable = 1000000
# Fill up the tables with random data
for x in xrange(lengthOfTable):
rand1 = random.random()
rand2 = random.random()
rand3 = random.random()
rand4 = random.random()
insertString = "INSERT INTO test_table_innodb (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
insertString2 = "INSERT INTO test_table_myisam (value1,value2,value3,value4) VALUES (" + str(rand1) + "," + str(rand2) + "," + str(rand3) + "," + str(rand4) + ")"
cur.execute(insertString)
cur.execute(insertString2)
for theLength in [3,10,30,100,300,1000,3000,10000,30000,100000]:
truncateString = "TRUNCATE subselect_innodb"
truncateString2 = "TRUNCATE subselect_myisam"
cur.execute(truncateString)
cur.execute(truncateString2)
# For each length, empty the table and re-fill it with random data
rand_sample = sorted(random.sample(xrange(lengthOfTable), theLength))
rand_sample_2 = random.sample(xrange(lengthOfTable), theLength)
for (the_value_1,the_value_2) in zip(rand_sample,rand_sample_2):
insertString = "INSERT INTO subselect_innodb (index_col,non_index_col) VALUES (" + str(the_value_1) + "," + str(the_value_2) + ")"
insertString2 = "INSERT INTO subselect_myisam (index_col,non_index_col) VALUES (" + str(the_value_1) + "," + str(the_value_2) + ")"
cur.execute(insertString)
cur.execute(insertString2)
db.commit()
# Finally, time the queries
innodb_times.append( timeit.timeit('subSelectRecordsIndexed("test_table_innodb","subselect_innodb")', number=100, setup=setupString) )
myisam_times.append( timeit.timeit('subSelectRecordsIndexed("test_table_myisam","subselect_myisam")', number=100, setup=setupString) )
innodb_times_2.append( timeit.timeit('subSelectRecordsNotIndexed("test_table_innodb","subselect_innodb")', number=100, setup=setupString2) )
myisam_times_2.append( timeit.timeit('subSelectRecordsNotIndexed("test_table_myisam","subselect_myisam")', number=100, setup=setupString2) )
이 모든 것의 교훈은 속도에 대해 정말로 관심이 있다면 어떤 엔진이 더 적합할지에 대한 가정을 하지 말고 현재 진행 중인 쿼리를 벤치마킹해야 한다는 것입니다.
약간 주제에서 벗어난 내용이지만, 문서화와 완전성을 위해 다음 사항을 추가하고 싶습니다.
일반적으로 InnoDB를 사용하면 훨씬 덜 복잡한 애플리케이션을 만들 수 있으며, 버그도 발생하지 않을 수 있습니다.모든 참조 무결성(외부 키 제약)을 데이터 모델에 넣을 수 있으므로 MyISAM에 필요한 만큼의 애플리케이션 코드가 필요하지 않습니다.
레코드를 삽입, 삭제 또는 교체할 때마다 관계를 확인하고 유지해야 합니다.예를 들어 부모를 삭제하면 모든 자식도 삭제해야 합니다.예를 들어 간단한 블로그 시스템에서도 블로그 게시 기록을 삭제하면 댓글 기록 등을 삭제해야 합니다.InnoDB에서는 데이터베이스 엔진(모델에서 제약조건을 지정한 경우)에 의해 자동으로 수행되며 애플리케이션 코드가 필요하지 않습니다.MyISAM 에서는, 이것을 애플리케이션에 코드화할 필요가 있습니다.이것은 웹 서버에서는 매우 어렵습니다.웹 서버는 본질적으로 매우 동시/병렬하며 이러한 동작은 원자적이고 MyISAM은 실제 트랜잭션을 지원하지 않기 때문에 웹 서버에 MyISAM을 사용하는 것은 위험하거나 오류가 발생하기 쉽습니다.
또한 대부분의 경우 InnoDB는 여러 가지 이유로 테이블 레벨 잠금과 달리 레코드 레벨 잠금을 사용할 수 있습니다.읽기보다 쓰기가 더 자주 발생하는 상황뿐만 아니라 대규모 데이터셋에 대한 복잡한 결합이 있는 상황에서도 마찬가지입니다.MyISAM 테이블보다 InnoDB 테이블을 사용하는 것만으로 성능이 3배 향상되었습니다(몇 분 소요).
일반적으로 MySQL을 사용할 때는 InnoDB(기준 무결성을 갖춘 3NF 데이터 모델 사용)가 기본 선택이 되어야 합니다.MyISAM은 매우 특별한 경우에만 사용해야 합니다.대부분의 경우 성능이 저하되고 결과적으로 응용 프로그램의 버그가 커집니다.
이런 말을 하다니.데이터 모델링은 웹디자이너/프로그래머 사이에서 거의 볼 수 없는 기술입니다.악의는 없지만 MyISAM이 그렇게 많이 사용되고 있는 것은 설명이 됩니다.
InnoDB의 특징:
ACID transactions
row-level locking
foreign key constraints
automatic crash recovery
table compression (read/write)
spatial data types (no spatial indexes)
InnoDB에서는 TEXT와 BLOB를 제외한 모든 데이터가 최대 8,000바이트를 차지할 수 있습니다.InnoDB에는 전체 텍스트 색인을 사용할 수 없습니다.InnoDB에서는 행 카운트가 내부적으로 저장되지 않기 때문에 COUNT(*)s(WHERE, GROUP BY 또는 JOIN을 사용하지 않을 경우)가 MyISAM에서보다 느리게 실행됩니다.InnoDB는 데이터와 인덱스를 하나의 파일에 저장합니다.InnoDB는 버퍼 풀을 사용하여 데이터와 인덱스를 모두 캐시합니다.
MyISAM의 특징:
fast COUNT(*)s (when WHERE, GROUP BY, or JOIN is not used)
full text indexing
smaller disk footprint
very high table compression (read only)
spatial data types and indexes (R-tree)
MyISAM에는 테이블레벨 잠금이 있지만 행레벨 잠금은 없습니다.트랜잭션은 없습니다.자동 크래시 리커버리 기능은 없지만 복구 테이블 기능을 제공합니다.외부 키 제약은 없습니다.MyISAM 테이블은 InnoDB 테이블과 비교하여 일반적으로 디스크 크기가 더 작습니다.MyISAM 테이블은 필요에 따라 myisampack을 사용하여 압축함으로써 크기를 더욱 크게 줄일 수 있지만 읽기 전용이 됩니다.MyISAM은 인덱스를 한 파일에 저장하고 데이터를 다른 파일에 저장합니다.MyISAM은 인덱스를 캐싱하기 위해 키 버퍼를 사용하고 데이터 캐싱 관리는 운영 체제에 맡깁니다.
전체적으로 InnoDB는 대부분의 용도로, MyISAM은 특별한 용도로만 사용하는 것을 추천합니다.InnoDB는 새로운 MySQL 버전에서 기본 엔진입니다.
MyISAM을 사용하는 경우 각 DML 문을 트랜잭션으로 간주하지 않는 한 시간당 트랜잭션은 수행되지 않습니다(어떤 경우에도 크래시 발생 시 내구성이 없거나 원자성이 없습니다).
따라서 InnoDB를 사용해야 한다고 생각합니다.
초당 300건의 트랜잭션이 꽤 많은 것 같네요.이러한 트랜잭션을 정전 후에도 안정적으로 수행해야 하는 경우 I/O 서브시스템이 초당 이렇게 많은 쓰기를 쉽게 처리할 수 있는지 확인하십시오.적어도 배터리 백업 캐시를 탑재한 RAID 컨트롤러가 필요합니다.
약간의 내구성 타격을 입을 수 있다면 innodb_flush_log_at_trx_commit을 0 또는 2로 설정한 InnoDB를 사용하면 성능을 향상시킬 수 있습니다(자세한 내용은 문서를 참조하십시오).
Google 등으로부터 동시성을 높일 수 있는 패치가 다수 있습니다.패치 없이 충분한 퍼포먼스를 얻을 수 없는 경우, 이러한 패치는 흥미로울 수 있습니다.
질문과 대부분의 답변이 최신이 아닙니다.
네, MyISAM이 InnoDB보다 빠르다는 것은 옛부터 알려진 이야기입니다.질문 날짜: 2008년, 지금은 거의 10년이 지났습니다.InnoDB는 그 이후 큰 성과를 거두고 있다.
그래프는 한 입니다.MyISAM은 MyISAM이 이겼습니다.COUNT(*)
없이WHERE
절을 클릭합니다.하지만 그게 정말 당신이 시간을 보내는 일인가요?
동시성 테스트를 실행하면 InnoDB가 이길 가능성이 매우 높아집니다.
SELECTs
및 , MyISAM »MEMORY
테이블 레벨 잠금으로 인해 손실될 수 있습니다.
실제로 오라클은 InnoDB가 더 낫다고 확신하고 있어 8.0에서 MyISAM을 거의 제거했다.
이 질문은 5.1년 초기에 작성되었습니다.그 이후 다음과 같은 주요 버전이 "General Availability"로 표시되었습니다.
- 2010년: 5.5(12월)
- 2013년 : 5.6 (2월 10일)
- 2015년 : 5.7 (10월 9일)
- 2018년: 8.0 (.4월 11일)
결론:MyISAM 사용 안 함
MySQL 자체에 대한 몇 가지 드롭다운 대체품도 확인하십시오.
마리아DB
MariaDB는 MySQL에 대한 드롭다운 대체 기능을 제공하는 데이터베이스 서버입니다.MariaDB는 MySQL의 원저작자 중 일부가 무료 및 오픈 소스 소프트웨어 개발자의 광범위한 커뮤니티의 지원을 받아 구축되었습니다.MySQL의 핵심 기능 외에도 MariaDB는 대체 스토리지 엔진, 서버 최적화 및 패치를 비롯한 다양한 기능 향상 기능을 제공합니다.
Percona 서버
https://launchpad.net/percona-server
향상된 성능, 향상된 진단 기능 및 추가 기능을 갖춘 MySQL의 향상된 드롭인 대체 기능.
MySQL에 대한 저의 공식 교육 및 경험은 Oracle에 대한 것이며 MySQL에 대한 저의 작업은 전적으로 개인적인 것이었기 때문에 Oracle에는 해당되지만 MySQL에는 해당되지 않는 것을 말씀 드린다면 사과드립니다.두 시스템은 많은 것을 공유하고 있지만, 관계 이론/대수는 같고, 관계 데이터베이스는 여전히 관계형 데이터베이스이지만, 여전히 많은 차이가 있습니다!!
특히 InnoDB가 트랜잭션 기반이라는 점이 마음에 듭니다. 즉, 웹 애플리케이션의 "작업"을 위해 여러 번 업데이트/삽입/작성/변경/폐기 등을 할 수 있습니다.문제는 이러한 변경/조작 중 일부만 커밋되고 나머지 일부는 커밋되지 않으면 대부분의 경우(데이터베이스의 특정 설계에 따라) 충돌하는 데이터/구조를 가진 데이터베이스가 생성된다는 것입니다.
주의: Oracle에서는 create/change/drop 스테이트먼트를 "DDL"(데이터 정의) 스테이트먼트라고 하며, 암묵적으로 커밋을 트리거합니다."DML"(데이터 조작)이라고 하는 삽입/갱신/삭제 문은 자동으로 커밋되지 않고 DDL, 커밋 또는 종료/종료를 수행할 때(또는 세션을 "auto-commit"으로 설정한 경우 또는 클라이언트가 자동으로 커밋하는 경우)에만 커밋됩니다.Oracle을 사용할 때는 반드시 알아야 하지만 MySQL이 두 가지 유형의 문을 어떻게 처리하는지 잘 모르겠습니다.그렇기 때문에 MySQL에 관해서는 Oracle에서만 확신할 수 없다는 것을 분명히 하고 싶습니다.
트랜잭션 기반 엔진이 우수한 경우의 예를 다음에 나타냅니다.
예를 들어, 저나 여러분이 무료 이벤트에 참가하기 위해 웹 페이지에 등록하고 있으며, 이 시스템의 주요 목적 중 하나는 최대 100명까지만 등록할 수 있는 것입니다. 왜냐하면 그것이 행사 좌석의 제한이기 때문입니다.100개의 등록에 도달하면 시스템은 적어도 다른 등록이 취소될 때까지 추가 등록을 비활성화합니다.
이 경우 게스트용 테이블(이름, 전화, 이메일 등)과 등록한 게스트 수를 추적하는 두 번째 테이블이 있을 수 있습니다.따라서 우리는 하나의 "거래"에 대해 두 개의 연산을 가지고 있습니다.이제 게스트 정보가 GUESTS 테이블에 추가된 후 연결이 끊기거나 동일한 영향을 미치는 오류가 발생했다고 가정합니다.GUESTS 테이블이 업데이트(에 삽입)되었지만 "사용 가능한 좌석"을 업데이트하기 전에 연결이 끊어졌습니다.
게스트 테이블에 게스트가 추가되었지만 현재 사용 가능한 좌석 수가 올바르지 않습니다(예를 들어 실제 84석일 경우 85석).
물론 '게스트 테이블에서 100줄 빼기'로 빈자리를 추적하거나 정보가 일치하는지 확인하는 코드 등 다양한 방법이 있습니다.그러나 InnoDB와 같은 트랜잭션 기반 데이터베이스 엔진에서는 모든 작업이 커밋되거나 커밋되지 않습니다.이것은 많은 경우에 도움이 될 수 있지만, 내가 말했듯이, 안전할 수 있는 유일한 방법은 아니다(그러나 이것은 프로그래머/스크립트 라이터가 아닌 데이터베이스에 의해 처리된다.
이 문맥에서 '트랜잭션 기반'은 기본적으로 제가 놓치고 있는 것이 아니라면 트랜잭션 전체가 정상적으로 성공하거나 아무것도 변경되지 않는 것을 의미합니다.부분적인 변경만 하면 데이터베이스의 사소한 혼란이나 심각한 혼란이 초래될 수 있기 때문입니다.아마도 파손될 수 있습니다.
하지만 다시 한 번 말하지만, 엉망진창이 되는 것을 피할 수 있는 유일한 방법은 아니에요.그러나 이 방법은 엔진 자체에서 처리하는 방법 중 하나이며, 데이터베이스 외부에서 수동으로 코드를 작성하고 이러한 이벤트에 대해 더 많은 작업을 수행하는 대신 "트랜잭션이 성공했는지 여부, 그리고 실패했을 경우(재시도 등)"만 걱정하면 됩니다.
마지막으로 테이블 잠금과 행 잠금에 관한 주의사항:
면책사항: MySQL에 관한 모든 점에서 틀릴 수 있습니다.가설/예시는 검토해야 할 사항입니다만, MySQL이 파손될 가능성이 있는 것은 틀릴 수 있습니다.그러나 MySQL이 이러한 문제를 피하기 위한 메커니즘을 더 많이 가지고 있더라도 일반적인 프로그래밍에서는 이러한 예가 매우 현실적입니다.
어쨌든, 한 번에 몇 개의 접속을 허용하는 것은 잠긴 테이블 주위에서 효과가 없다고 주장하는 사람들의 의견에 동의하는 것은 꽤 자신 있습니다.실제로 테이블을 잠글 때는 여러 개의 접속이 포인트입니다.따라서 다른 프로세스/사용자/앱이 동시에 변경함으로써 데이터베이스를 손상시킬 수 없습니다.
두 개 이상의 연결이 같은 행에서 작동하면 어떻게 하면 정말 안 좋은 날이 될 수 있습니까?같은 행에 같은 값을 갱신하거나 갱신할 필요가 있는 프로세스가 2개 있다고 가정합니다.예를 들어, 이 행은 버스 투어의 레코드이며, 2개의 프로세스 각각이 동시에 "리더스" 또는 "available_sats" 필드를 "current value + 1"로 갱신하려고 합니다.
이것을 가정해서 단계별로 실행해 봅시다.
- 프로세스 1은 현재 값을 읽습니다. 비어 있다고 가정하면 지금까지 '0'입니다.
- 프로세스 2는 현재 값도 읽습니다.이 값은 0입니다.
- 프로세스 1의 기입(전류+1)은 1입니다.
- 프로세스 2는 2를 써야 하는데 프로세스 1이 새로운 값을 쓰기 전에 현재 값을 읽기 때문에 1도 테이블에 씁니다.
두 개의 연결이 그렇게 섞일 수 있을지는 모르겠지만 첫 번째 연결은 쓰기 전에 읽어야 해그러나 그렇지 않은 경우에도 다음과 같은 문제가 발생합니다.
- 프로세스 1은 현재 값인 0을 읽습니다.
- 프로세스 1 기입(전류 + 1)은 1입니다.
- 프로세스 2는 현재 값을 읽습니다.그러나 프로세스 1 DID 쓰기(갱신) 중에는 데이터가 커밋되지 않았기 때문에 커밋이 있을 때까지 동일한 프로세스만 갱신한 새 값을 읽을 수 있습니다.다른 모든 프로세스에서는 이전 값을 볼 수 있습니다.
또, 적어도 Oracle 데이터베이스에는 격리 레벨이 있기 때문에, 시간을 낭비하지 않습니다.다음은 해당 주제에 대한 좋은 기사입니다. 각 격리 수준에는 장단점이 있습니다. 이는 트랜잭션 기반 엔진이 데이터베이스에서 얼마나 중요한지에 따라 달라집니다.
마지막으로, MyISAM 내에는 외부 키 및 트랜잭션 기반 상호작용 대신 다양한 안전장치가 있을 수 있습니다.예를 들어 테이블 전체가 잠겨 있기 때문에 트랜잭션/FK가 필요하지 않습니다.
게다가 이러한 동시성 문제를 알고 있는 경우는, 보다 안전성이 저하해, 애플리케이션을 써넣기만 하면 됩니다.또, 그러한 에러가 발생하지 않게 시스템을 셋업 할 수도 있습니다(데이터베이스가 아니고, 코드에 책임이 있습니다).다만, 가능한 한 많은 세이프가드를 사용해, 방어적으로 프로그래밍 해, 인간의 실수는 완전하게 회피할 수 없다는 것을 항상 의식하는 것이 최선이라고 생각합니다.누구에게나 일어나는 일이며, 면역력이 있다고 말하는 사람은 거짓말을 하거나 "Hello World" 어플리케이션/스크립트를 작성하는 것 이상을 하지 않은 사람일 것입니다. ;-)
그 중 몇 가지는 누군가에게 도움이 되고, 더더욱, 내가 지금 단지 추측의 범인이 되어 인간이 되는 것은 아니었으면 좋겠다!!만약 그렇다면 죄송하지만, 이 예들은 이 특정한 맥락에서 잠재력이 없더라도 생각하고, 위험성을 조사하는 것이 좋습니다.
얼마든지 수정하고, 이 "답안"을 수정하고, 부결시키세요.제 잘못된 가정을 다른 것으로 바로잡지 말고 개선해 주세요. ;-)
첫 회답이니, 면책사항 등으로 인해 시간이 걸리는 점 양해 부탁드립니다.내가 확실히 확신하지 못할 때 거만하게 굴고 싶지 않을 뿐이에요!
저는 이 기사가 차이점을 설명하고 다른 기사를 사용해야 할 시기에 대한 훌륭한 기사라고 생각합니다.http://tag1consulting.com/MySQL_Engines_MyISAM_vs_InnoDB
내 경험상, MyISAM은 DELETE, UPDATE, 단일 INSERT, 트랜잭션 및 전체 텍스트 인덱싱을 수행하지 않는 한 더 나은 선택이었습니다.그나저나, 체크테이블은 끔찍해테이블이 행의 수에 따라 오래되면 언제 끝날지 알 수 없습니다.
Myisam은 잠금 경합이 있지만 빠른 잠금 획득 방식으로 인해 대부분의 시나리오에서 InnoDb보다 빠르다는 것을 알게 되었습니다.나는 Innodb를 여러 번 시도했지만, 이런저런 이유로 항상 MyIsam으로 돌아간다.또한 InnoDB는 대량의 쓰기 부하에서 CPU를 매우 많이 소모할 수 있습니다.
애플리케이션마다 데이터베이스를 사용하기 위한 자체 성능 프로파일이 있으며 시간이 지남에 따라 변경될 수 있습니다.
최선의 방법은 옵션을 테스트하는 것입니다.MyISAM과 InnoDB의 전환은 간단하므로 테스트 데이터를 로드하여 사이트에 jmeter를 발사하여 어떤 일이 일어나는지 확인하십시오.
MyISAM과 InnoDB 테이블에 랜덤 데이터 삽입을 시도했습니다.결과는 꽤 충격적이었다.MyISAM은 InnoDB보다 100만 행 삽입에 단 몇 초가 적게 소요되었습니다.
myisam은 이러한 종류의 워크로드(높은 동시 쓰기)에 대한 NOGO입니다.innodb에 대한 경험이 별로 없습니다(각 케이스에서 3번 테스트하여 성능이 저하되었지만 마지막 테스트 이후 시간이 좀 지났습니다). mysql을 실행할 필요가 없다면 postgres를 동시에 쓰는 것이 훨씬 좋습니다.
즉, InnoDB는 많은 INSERT 및 UPDATE 명령을 처리할 수 있는 신뢰할 수 있는 데이터베이스를 필요로 하는 경우에 적합합니다.
또한 MyISAM은 테이블 잠금과 관련된 단점을 고려할 때 쓰기(INSERT 및 UPDATES)보다는 읽기(SELECT) 명령을 많이 사용하는 데이터베이스가 필요한 경우에 적합합니다.
좋을 것
InnoDB inno inno inno inno inno inno
MyISAMMyISAM의
별로 인기가 없을 거라는 건 알지만, 이렇게 하자.
myISAM은 트랜잭션이나 참조 무결성과 같은 데이터베이스 필수 요소를 지원하지 않으며, 이로 인해 종종 결함이 있거나 버그가 있는 애플리케이션이 발생합니다.데이터베이스 설계의 기본이 db 엔진에서 지원되지 않으면 제대로 된 데이터베이스 설계의 기본을 배울 수 없습니다.
데이터베이스 세계에서 참조 무결성 또는 트랜잭션을 사용하지 않는 것은 소프트웨어 세계에서 객체 지향 프로그래밍을 사용하지 않는 것과 같습니다.
InnoDB가 지금 존재합니다.대신 그것을 사용하세요!MySQL 개발자들조차 새로운 버전에서는 이를 기본 엔진으로 변경하는 것을 인정했습니다.ISAM은 모든 레거시시스템 디폴트 엔진입니다
아니요, 읽기 또는 쓰기, 퍼포먼스에 관한 고려사항, my-my-my-my-my-my-my-my-my-my-my-ISAM은 다음과 같은 다양한 문제를 일으킬 수 있습니다.데이터베이스 동기화를 수행 중 다른 사용자가 myISAM으로 설정된 테이블에 액세스하는 응용 프로그램에 액세스했습니다.트랜잭션 지원이 부족하고 이 엔진은 일반적으로 신뢰성이 떨어지기 때문에 데이터베이스 전체가 크래시되어 mysql을 수동으로 재시작해야 했습니다!
지난 15년간 많은 데이터베이스와 엔진을 사용해 왔습니다.myISAM은 이 기간 동안 수십 번, 다른 데이터베이스는 단 한 번, 나에게 충돌했습니다.그리고 그것은 마이크로소프트 SQL 데이터베이스로, 개발자가 CLR 코드(공통 언어 런타임-기본적으로 데이터베이스 내부에서 실행되는 C# 코드)를 기술한 것입니다.그것은 데이터베이스 엔진의 잘못이 아닙니다.
고품질의 고가용성(HA)과 고성능(High-Performance) 어플리케이션에서는 다음 명령어를 사용하지 않아야 한다는 다른 답변에 동의합니다.ISAM은 동작하지 않기 때문에 견고하지 않고 안정적이지 않기 때문에 좌절감이 없습니다.자세한 내용은 Bill Karwin의 답변을 참조하십시오.
추신. 내 마음에 들거야ISAM 팬보이는 다운투표를 하지만 이 답변의 어느 부분이 틀렸는지 말해줄 수 없다.
읽기/쓰기 비율은 InnoDB가 더 좋을 것 같습니다.지저분한 읽기는 문제없기 때문에 여유가 있는 경우 슬레이브에 복제하여 모든 읽기를 슬레이브로 보낼 수 있습니다.또한 레코드를 한 번에 하나씩 삽입하는 것이 아니라 대량으로 삽입하는 것이 좋습니다.
거의 매번 새로운 프로젝트를 시작할 때마다 새로운 답을 찾기 위해 구글에서 같은 질문을 합니다.
결국 MySQL의 최신 버전을 사용하여 테스트를 실행합니다.
키/값 검색을 수행할 테이블이 있습니다.그리고 그게 다에요.해시 키의 값(0-512바이트)을 취득할 필요가 있습니다.이 DB에는 트랜잭션이 많지 않습니다.테이블은 때때로(전체) 업데이트를 받지만 트랜잭션은 0입니다.
여기서 말하는 것은 복잡한 시스템이 아니라 단순한 룩업에 대해 말하는 것입니다.또한 (테이블 RAM을 설치하는 것 외에) 퍼포먼스를 최적화할 수 있는 방법에 대해서도 말하고 있습니다.
다른 데이터베이스(NoSQL)에서도 테스트하여 이점을 얻을 수 있는 곳이 있는지 확인합니다.제가 찾은 가장 큰 장점은 키 맵핑이지만, 조회 결과로는 MyISAM이 모든 항목에서 1위를 차지하고 있습니다.
MyISAM 테이블로 금융거래를 하는 것은 아니지만, 간단한 조회는 테스트해 보는 것이 좋습니다.일반적으로 초당 2~5배의 쿼리 수를 가집니다.
시험해봐, 난 토론을 환영해.
70%의 삽입과 30%의 판독이라면 InnoDB 쪽에 가깝습니다.
결론: 오프라인에서 대량의 데이터 청크를 선택하여 작업하는 경우 MyISAM을 통해 더 빠른 속도를 얻을 수 있습니다.
MyISAM이 InnoDB보다 훨씬 더 효율적인 경우가 있습니다. 오프라인에서 대용량 데이터 덤프를 조작하는 경우(테이블 잠금으로 인해).
예:VARCHAR 필드를 키로 하는 NOAA의 csv 파일(1500만 레코드)을 변환하고 있었습니다.InnoDB는 대용량의 메모리를 사용해도 시간이 오래 걸렸습니다.
csv의 예를 다음에 나타냅니다(첫 번째 필드와 세 번째 필드는 키입니다).
USC00178998,20130101,TMAX,-22,,,7,0700
USC00178998,20130101,TMIN,-117,,,7,0700
USC00178998,20130101,TOBS,-28,,,7,0700
USC00178998,20130101,PRCP,0,T,,7,0700
USC00178998,20130101,SNOW,0,T,,7,
관측된 날씨 현상의 일괄 오프라인 업데이트를 실행하는 것이 필요하기 때문에 데이터를 수신하기 위해 MyISAM 테이블을 사용하고 키에 대해 JOINS를 실행하여 들어오는 파일을 정리하고 VARCHAR 필드를 INT 키(원래 VARCHAR 값이 저장된 외부 테이블과 관련됨)로 바꿀 수 있습니다.
언급URL : https://stackoverflow.com/questions/20148/myisam-versus-innodb
'itsource' 카테고리의 다른 글
DatabaseError: 현재 트랜잭션이 중단되었습니다. 트랜잭션 블록이 끝날 때까지 명령이 무시됩니까? (0) | 2022.09.23 |
---|---|
JavaScript에서 시간대 이름을 얻으려면 어떻게 해야 하나요? (0) | 2022.09.23 |
MySQL이 접두사 인덱스의 쿼리를 충족할 수 있습니까? (0) | 2022.09.23 |
X-Macros의 실제 사용 (0) | 2022.09.23 |
JavaScript:오류 콘솔에 메시지를 인쇄하려면 어떻게 해야 하나요? (0) | 2022.09.23 |