2012-01-13 2 views
1

* 당신은 당신이 결국 내 질문을 찾을 수있는 설명을 읽어 게으른 경우 ...MySQL의 삽입 성능 stressTool

안녕, 나는 간단한 데이터베이스 구축 : 이제 내가

CREATE TABLE `users` (
    `id` varchar(45) NOT NULL, 
    `full_name` varchar(45) NOT NULL, 
    `first_name` varchar(45) NOT NULL, 
    `last_nmae` varchar(45) NOT NULL, 
    `login` varchar(45) NOT NULL, 
    `password` varchar(45) NOT NULL, 
    PRIMARY KEY (`id`,`full_name`,`login`), 
    UNIQUE KEY `idusers_UNIQUE` (`id`), 
    UNIQUE KEY `login_UNIQUE` (`login`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 

을 단일 행 삽입의 성능 테스트.

나는 C#으로 스트레스 도구를 만들고 1M 행으로 실행합니다. doJob() 메소드에서

abstract class Job 
    { 
     private static object synObject = new object(); 
     private static int _id = 0; 
     private static DateTime startingTime = DateTime.Now; 
     private const int JOB_PER_SIRCLE = 10; 

     protected int id; 
     public Job() 
     { 
      lock (synObject) 
      { 
       _id++; 
       id = _id; 
      } 
     } 

     public void run() 
     { 
      while (true) 
      { 
       for (int i = 0; i < JOB_PER_SIRCLE; i++) 
       { 
        doJob(); 
       } 
       lock (synObject) 
       { 
        calculate(); 
       } 
      } 
     } 

     private static DateTime lastLog = DateTime.Now; 
     private static long numOfJobsAcomplished = 0; 
     private static long totalNumOfJobsAcomplished = 0; 

     private static void calculate() 
     { 
      totalNumOfJobsAcomplished += JOB_PER_SIRCLE; 
      numOfJobsAcomplished += JOB_PER_SIRCLE; 
      DateTime now = DateTime.Now; 
      TimeSpan timePass = now - lastLog; 

      if (timePass.TotalSeconds > 1) 
      { 
       double total = 1000000; 
       TimeSpan speed = TimeSpan.FromMilliseconds(timePass.TotalMilliseconds/numOfJobsAcomplished * total); 
       Console.WriteLine("Speed = " + String.Format("{0:00.0000}", speed.TotalMinutes) + " Completed " + String.Format("{0:00.000}", totalNumOfJobsAcomplished/total * 100) + "% time pass " + (now - startingTime)); 
       lastLog = now; 
       numOfJobsAcomplished = 0; 
      } 
     } 

     protected abstract void doJob(); 
    } 

내가 삽입을하고있는 중이 야 내가 16 욥의, 16 개 스레드 (나는 내 ​​컴퓨터에 최적의 성능을 것으로 나타났습니다) 실행하고 있습니다 : 당신이 관심이 있다면 이 코드입니다

어쨌든 제 질문은 결과에 관한 것입니다. 나는 85 만에서 105 분 사이에 1,000,000 개의 행을 삽입하려고합니다. 이 속도가 빠르거나 다른 데이터베이스를 사용해야합니까?

P.S * 나는 또한 내가 항상 누군가를 고려하여 다른 요인을 고려하지 않고 소프트웨어에 대한 "비난"쓰기 속도에 시도 재미 때 찾을 MD5Crypt 알고리즘

+1

'이것이 빠릅니다'는 주관적입니다. 요구 사항 및/또는 제약 조건은 무엇입니까?로드 동작은 실제로 어떤 것입니까? 테이블에서 다른 읽기 또는 쓰기 활동은 어떻게됩니까? 또한 SQL 쿼리의 형식이 중요합니다. 매개 변수화 된 쿼리를 사용하여 네트워크 트래픽을 최소화하고 시간을 파싱하고 컴파일하는 등의 작업을 수행하고 있습니까? – MatBailie

+0

@Dems "사용자 값 ('...')에 삽입;" –

+0

매개 변수화 된 쿼리를 살펴보십시오. 동일한 쿼리를 반복해서 반복하면 더 빠르게 수행됩니다. – MatBailie

답변

1

해싱 삽입하고있다. 그럼 시작 하죠.

MySQL에는 널리 사용되는 2 개의 엔진이 있습니다. MyISAM과 InnoDB. InnoDB는 클러스터 된 기본 키를 사용하여 레코드를 hdd에 기록하는 트랜잭션 엔진입니다. 즉, 디스크에 안전하게 데이터를 쓰고 서로 옆에 순차 레코드가 기록되도록 모든 종류의 계산을 수행합니다. 기본 키 조회 사용은 빠르지 만 적어 두는 데는 시간이 걸립니다.

이것을 평이한 영어로 번역하면 컴퓨터가 디스크 에 데이터를 물리적으로 쓰기가 약간 더 힘들어지며 기록을 빨리 찾을 수 있습니다.

또한이 모든 고난의 병목 현상이 하드 드라이브라는 것을 의미합니다. 1mil을 삽입하려면 85 분. 레코드는 초당 약 200 인서트입니다. 평범한 7200 RPM 기계식 드라이브 (내 드라이브는 350 입출력 (IOPS)에 도달 할 수 있습니다.)는 꽤 좋은 수치입니다. 그래서 350 IOPS (내 드라이브를 가져 가자)에서 200을 얻었는데 이는 HDD가 읽기 및 쓰기에 사용된다는 것을 보여주는 훌륭한 수치이며 HDD 입출력이 필요한 OS에서 여러 가지 서비스를 실행했을 가능성이 높습니다.

TL - DR - 다른 소프트웨어를 사용하는 경우 쓰기가 약간 더 빨라질 수 있습니다. 소프트웨어를 교환하기 전에 모든 요소를 ​​고려해야합니다.

+0

나는 MySQL을 탓한다고 말하지 않았다. 나는 단지 이것이 좋은 속도인지 아닌지 이해하려고 노력하고있다. 서버를 시작할 때 많은 일이 진행됩니다. 좋은 성능의 비행기를 만들고 싶습니다. –

+0

삽입 속도가 하드웨어, 특히 HDD 하위 시스템에 따라 달라지는 것을 보여주고 있습니다. 기본적으로 예, 기계식 7200 RPM hdd의 경우 속도는 괜찮습니다. –

0

삽입 성능을 최적화하려면 기본 키를 합성 자동 증가 bigint로 변경하는 것이 좋습니다. 그 이유는 Innodb이 범위별로 키를 저장하는 기본 키에 클러스터 된 인덱스를 사용하기 때문입니다. 순차적이지 않은 기본 키를 사용하는 경우 순차 키를 사용하는 것처럼 캐시를 사용하는 대신 최악의 경우 메모리 블록을 읽고 각 행에 다시 써야합니다. 순차 키를 삽입하면 성능이 몇 배 증가하여 시용하십시오.

CREATE TABLE `users` (
    `id` bigint(20) auto increment not null PRIMARY KEY, 
    `user_id` varchar(45) NOT NULL, 
    `full_name` varchar(45) NOT NULL, 
    `first_name` varchar(45) NOT NULL, 
    `last_nmae` varchar(45) NOT NULL, 
    `login` varchar(45) NOT NULL, 
    `password` varchar(45) NOT NULL, 
    UNIQUE KEY (`user_id`,`full_name`,`login`), 
    UNIQUE KEY `idusers_UNIQUE` (`user_id`), 
    UNIQUE KEY `login_UNIQUE` (`login`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 

BTW, 나는 그래서에서 떠나기 전에 무엇 ID (USER_ID) 모르겠지만, 합성 기본 키로 사용 어디는 경우 그것을 걸릴 수 있습니다.

+0

확인 테스트를 실행하면 성능에 아무런 영향을 미치지 않는 것 같습니다. –

+0

시도한 행 수는 얼마나됩니까? 또한 innodb_buffer_size가 제대로 설정되었는지 확인하고 싶습니다. 지금 설정되어있는 것은 무엇입니까? –

+0

innodb_buffer_size 란 무엇입니까? –