[mysql] MyISAM 및 InnoDB 비교

나는 많은 데이터베이스 쓰기를 포함하는 프로젝트를 진행하고 있다고 말합니다 ( 70 % 삽입 및 30 % 읽기 ). 이 비율에는 한 번의 읽기와 한 번의 쓰기로 간주되는 업데이트도 포함됩니다. 읽기가 더러울 수 있습니다 (예 : 읽을 때 100 % 정확한 정보가 필요하지 않습니다).
문제는 한 시간에 백만 건 이상의 데이터베이스 트랜잭션을 수행하는 것입니다.

웹에서 MyISAM과 InnoDB의 차이점에 대한 많은 자료를 읽었으며 MyISAM 은이 작업에 사용할 특정 데이터베이스 / 테이블에 대한 확실한 선택 인 것 같습니다. 내가 읽고있는 것부터 행 수준 잠금이 지원되므로 트랜잭션이 필요한 경우 InnoDB가 좋습니다.

이 유형의 하중 (또는 그 이상)에 경험이 있습니까? MyISAM이가는 길입니까?



답변

이 질문에 대해 간략히 설명 했으므로 InnoDB 또는 MyISAM 중 어떤 것을 사용할 것인지 결정할 수 있습니다 .

다음은 어떤 상황에서 어떤 DB 스토리지 엔진을 사용해야하는지에 대한 간단한 개요입니다.

                                                 MyISAM InnoDB
-------------------------------------------------- --------------
필요한 전체 텍스트 검색 예 5.6.4
-------------------------------------------------- --------------
거래 필요 예
-------------------------------------------------- --------------
자주 묻는 질문 예
-------------------------------------------------- --------------
자주 삽입, 업데이트, 삭제 예
-------------------------------------------------- --------------
행 잠금 (단일 테이블에서 다중 처리) 예
-------------------------------------------------- --------------
관계형 기본 설계

요약

  • 거의 모든 상황에서 InnoDB 가 가장 좋은 방법입니다
  • 그러나 자주 읽지 않고 거의 글을 쓰지 않으면 MyISAM을 사용하십시오.
  • MySQL <= 5.5에서 전체 텍스트 검색, MyISAM 사용

답변

저는 데이터베이스 전문가가 아니며 경험을 바탕으로 이야기하지 않습니다. 하나:

MyISAM 테이블은 테이블 레벨 잠금을 사용합니다 . 예상 트래픽을 기반으로 초당 약 200 회의 쓰기가 가능합니다. MyISAM을 사용하면 언제든지이 중 하나만 진행할 수 있습니다 . 오버런을 피하기 위해 하드웨어가 이러한 트랜잭션을 유지할 수 있는지 확인해야합니다. 즉, 단일 쿼리는 5ms를 넘을 수 없습니다.

즉, InnoDB와 같은 행 수준 잠금을 지원하는 스토리지 엔진이 필요합니다.

반면에 각 스토리지 엔진의로드를 시뮬레이트하기 위해 몇 가지 간단한 스크립트를 작성한 다음 결과를 비교하는 것이 매우 간단합니다.


답변

사람들은 종종 성능, 읽기 대 쓰기, 외래 키 등에 대해 이야기하지만 원자력 업데이트 라는 또 다른 견해로는 스토리지 엔진의 또 다른 필수 기능이 있습니다.

이 시도:

  1. 5 초가 걸리는 MyISAM 테이블에 대해 UPDATE를 발행하십시오.
  2. UPDATE가 진행되는 동안 (예 : 2.5 초) Ctrl-C를 눌러 중단하십시오.
  3. 테이블에 미치는 영향을 관찰하십시오. 몇 개의 행이 업데이트 되었습니까? 몇 개가 업데이트되지 않았습니까? 테이블을 읽을 수 있거나 Ctrl-C를 눌렀을 때 손상 되었습니까?
  4. InnoDB 테이블에 대해 UPDATE로 동일한 실험을 수행하여 진행중인 쿼리를 중단하십시오.
  5. InnoDB 테이블을 관찰하십시오. 제로 행이 업데이트되었습니다. InnoDB는 원자 업데이트를 보장했으며 전체 업데이트를 커밋 할 수없는 경우 전체 변경 사항을 롤백합니다. 또한 테이블이 손상되지 않았습니다. killall -9 mysqld충돌을 시뮬레이션하는 데 사용 하는 경우에도 작동합니다 .

물론 성능이 바람직하지만 데이터잃지 않는 것이 우선합니다.


답변

MySQL을 사용하는 대용량 시스템에서 작업했으며 MyISAM과 InnoDB를 모두 시도했습니다.

MyISAM의 테이블 수준 잠금으로 인해 워크로드에 심각한 성능 문제가 발생하여 사용자와 유사한 것으로 나타났습니다. 불행히도 나는 또한 InnoDB의 성능이 기대보다 좋지 않다는 것을 알았습니다.

결국 삽입이 “핫”테이블로 이동하고 핫 테이블을 쿼리하지 않도록 선택하도록 데이터를 조각화하여 경합 문제를 해결했습니다.

이것은 또한 선택 쿼리에 의해 건드리지 않은 “stale”테이블에서 삭제 (데이터가 시간에 민감하고 X 일만 보존)를 허용했습니다. InnoDB는 대량 삭제시 성능이 떨어지는 것 같습니다. 따라서 데이터를 제거하려는 경우 오래된 데이터가 오래된 테이블에 삭제를 실행하는 대신 간단히 삭제할 수있는 방식으로 데이터를 구성 할 수 있습니다.

물론 응용 프로그램이 무엇인지 모르지만 MyISAM 및 InnoDB의 일부 문제에 대한 통찰력을 얻을 수 있기를 바랍니다.


답변

게임에 조금 늦었지만 … 여기 에 몇 달 전에 쓴 MYISAM과 InnoDB의 주요 차이점을 자세하게 설명한 포괄적 인 게시물이 있습니다. 컵파 (아마도 비스킷)를 잡고 즐기십시오.


MyISAM과 InnoDB의 주요 차이점은 참조 무결성과 트랜잭션에 있습니다. 잠금, 롤백 및 전체 텍스트 검색과 같은 다른 차이점도 있습니다.

참조 무결성

참조 무결성은 테이블 간의 관계가 일관되게 유지되도록합니다. 보다 구체적으로 말하면, 테이블 (예 : 리스팅)에 다른 테이블 (예 : 제품)을 가리키는 외래 키 (예 : 제품 ID)가 있고, 지정된 테이블에 대한 업데이트 또는 삭제가 발생하면 이러한 변경 사항이 연결에 연결됩니다. 표. 이 예에서 제품 이름이 바뀌면 연결 테이블의 외래 키도 업데이트됩니다. ‘제품’테이블에서 제품을 삭제하면 삭제 된 항목을 가리키는 모든 목록도 삭제됩니다. 또한 새 목록에는 유효한 기존 항목을 가리키는 외래 키가 있어야합니다.

InnoDB는 관계형 DBMS (RDBMS)이므로 참조 무결성이 있지만 MyISAM은 그렇지 않습니다.

거래 및 원 자성

테이블의 데이터는 SELECT, INSERT, UPDATE 및 DELETE와 같은 DML (Data Manipulation Language) 문을 사용하여 관리됩니다. 트랜잭션 그룹은 둘 이상의 DML 문을 단일 작업 단위로 함께 묶어 전체 단위가 적용되거나 전혀 적용되지 않습니다.

MyISAM은 트랜잭션을 지원하지 않지만 InnoDB는 지원합니다.

MyISAM 테이블을 사용하는 동안 작업이 중단되면 작업이 즉시 중단되고 작업이 완료되지 않은 경우에도 영향을받는 행 (또는 각 행 내의 데이터)이 영향을받습니다.

원 자성을 가진 트랜잭션을 사용하기 때문에 InnoDB 테이블을 사용하는 동안 작업이 중단되면 커밋이 수행되지 않으므로 완료되지 않은 트랜잭션은 적용되지 않습니다.

테이블 잠금 대 행 잠금

MyISAM 테이블에 대해 쿼리를 실행하면 쿼리하는 전체 테이블이 잠 깁니다. 이는 후속 쿼리가 현재 쿼리가 완료된 후에 만 ​​실행됨을 의미합니다. 큰 테이블을 읽거나 읽기 및 쓰기 작업이 자주 발생하는 경우 쿼리에 대한 백 로그가 엄청날 수 있습니다.

InnoDB 테이블에 대해 쿼리를 실행할 때 관련된 행만 잠기고 나머지 테이블은 CRUD 작업에 사용할 수 있습니다. 이는 동일한 행을 사용하지 않는 한 동일한 테이블에서 쿼리를 동시에 실행할 수 있음을 의미합니다.

InnoDB의이 기능은 동시성이라고합니다. 동시성이있는 한, 엄선 된 테이블 범위에 적용되는 주요 단점이 있습니다. 커널 스레드간에 전환하는 데 오버 헤드가 있으므로 서버가 중지되지 않도록 커널 스레드에 제한을 설정해야합니다. .

거래 및 롤백

MyISAM에서 작업을 실행하면 변경 사항이 설정됩니다. InnoDB에서는 이러한 변경 사항을 롤백 할 수 있습니다. 트랜잭션을 제어하는 ​​데 사용되는 가장 일반적인 명령은 COMMIT, ROLLBACK 및 SAVEPOINT입니다. 1. COMMIT-여러 DML 작업을 작성할 수 있지만 COMMIT가 수행 될 때만 변경 사항이 저장됩니다. 2. ROLLBACK-아직 커밋되지 않은 작업은 모두 버릴 수 있습니다. 3. SAVEPOINT-목록에서 포인트를 설정합니다. ROLLBACK 조작이 롤백 할 수있는 조작

신뢰할 수 있음

MyISAM은 데이터 무결성을 제공하지 않습니다. 하드웨어 오류, 부정한 종료 및 취소 된 작업으로 인해 데이터가 손상 될 수 있습니다. 인덱스와 테이블을 완전히 복구하거나 다시 작성해야합니다.

반면 InnoDB는 트랜잭션 로그, 이중 쓰기 버퍼 및 자동 체크섬 및 유효성 검사를 사용하여 손상을 방지합니다. InnoDB는 변경하기 전에 트랜잭션 이전의 데이터를 ibdata1이라는 시스템 테이블 스페이스 파일에 기록합니다. 충돌이 발생하면 InnoDB는 해당 로그 재생을 통해 자동 복구합니다.

전체 텍스트 인덱싱

InnoDB는 MySQL 버전 5.6.4까지 FULLTEXT 인덱싱을 지원하지 않습니다. 이 글을 쓰는 현재 많은 공유 호스팅 제공 업체의 MySQL 버전이 여전히 5.6.4 미만이므로 InnoDB 테이블에서 FULLTEXT 인덱싱이 지원되지 않습니다.

그러나 이것이 MyISAM을 사용하는 유효한 이유는 아닙니다. 최신 버전의 MySQL을 지원하는 호스팅 제공 업체로 변경하는 것이 가장 좋습니다. FULLTEXT 인덱싱을 사용하는 MyISAM 테이블을 InnoDB 테이블로 변환 할 수있는 것은 아닙니다.

결론

결론적으로 InnoDB는 기본 스토리지 엔진으로 선택해야합니다. 특정 요구에 맞는 MyISAM 또는 기타 데이터 유형을 선택하십시오.


답변

더 많은 쓰기 및 읽기가있는로드의 경우 InnoDB의 이점이 있습니다. InnoDB는 테이블 잠금이 아닌 행 잠금을 제공하기 때문에 SELECT서로간에뿐만 아니라 많은로도 동시에 동기화 될 수 있습니다 INSERT. 그러나 SQL 트랜잭션을 사용하지 않으려면 InnoDB 커밋 플러시를 2 ( innodb_flush_log_at_trx_commit )로 설정하십시오. 이것은 테이블을 MyISAM에서 InnoDB로 옮길 때 잃어버린 많은 원시 성능을 다시 제공합니다.

또한 복제 추가를 고려하십시오. 이를 통해 약간의 읽기 조정이 가능하며 읽기가 최신 상태 일 필요는 없다고 언급 했으므로 복제가 약간 뒤쳐 질 수 있습니다. 교통량이 가장 많거나 항상 뒤쳐 질 수 있으며 절대로 뒤지지 않을 것입니다. 그러나이 방법으로 이동 하면 슬레이브 및 복제 지연 관리에서 데이터베이스 처리기로 읽기를 분리 하는 것이 좋습니다. 응용 프로그램 코드가 이것에 대해 알지 못하면 훨씬 간단합니다.

마지막으로, 다른 테이블로드에주의하십시오. 모든 테이블에서 동일한 읽기 / 쓰기 비율을 갖지는 않습니다. 100 %에 가까운 판독 값을 가진 일부 작은 테이블은 MyISAM을 유지할 수 있습니다. 마찬가지로 100 % 쓰기에 가까운 일부 테이블이있는 경우에는 이점이 INSERT DELAYED있지만 MyISAM에서만 지원됩니다 ( DELAYEDInnoDB 테이블 에서는이 절이 무시 됨).

그러나 벤치마킹해야합니다.


답변

두 엔진 간의 기계적 차이를 다루는 다양한 응답을 추가하기 위해 경험적 속도 비교 연구를 제시합니다.

순수한 속도면에서, MyISAM이 InnoDB보다 빠른 경우는 아니지만 제 경험상 PURE READ 작업 환경에서는 약 2.0-2.5 배 더 빠릅니다. 다른 환경이 작성한 것처럼 MyISAM에는 트랜잭션 및 외래 키와 같은 기능이 없습니다.

아래에서 약간의 벤치마킹을 수행했습니다. 루핑에는 파이썬을 사용하고 타이밍 비교에는 timeit 라이브러리를 사용했습니다. 관심을 끌기 위해 메모리 엔진도 포함 시켰으므로 작은 테이블에만 적합하지만 The table 'tbl' is fullMySQL 메모리 제한을 초과 하면 계속 발생 합니다. 내가 본 네 가지 유형의 선택은 다음과 같습니다.

  1. 바닐라 선택
  2. 카운트
  3. 조건부 선택
  4. 인덱싱 및 인덱싱되지 않은 하위 선택

먼저 다음 SQL을 사용하여 세 개의 테이블을 만들었습니다.

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

두 번째 및 세 번째 테이블에서 ‘MyISAM’이 ‘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가 승리

이 쿼리에서는 하위 선택을위한 추가 테이블 세트를 작성했습니다. 각각은 기본 키 인덱스가 있고 다른 하나는 인덱스가없는 BIGINT의 두 열입니다. 큰 테이블 크기로 인해 메모리 엔진을 테스트하지 않았습니다. SQL 테이블 작성 명령은

CREATE TABLE
    subselect_myisam
    (
        index_col bigint NOT NULL,
        non_index_col bigint,
        PRIMARY KEY (index_col)
    )
    ENGINE=MyISAM DEFAULT CHARSET=utf8;

다시 한번, ‘MyISAM’은 두 번째 테이블에서 ‘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) )

이 모든 것의 핵심 메시지는 속도에 정말로 관심 이 있다면 어떤 엔진이 더 적합한 지에 대한 가정을하기보다는 수행중인 쿼리를 벤치 마크해야한다는 것입니다.