쿼리

2011-01-28 4 views
2

내가 라인으로 데이터 피드 라인을 읽고 분석하고 MyISAM 테이블에 데이터를 삽입하는 방법이있다. 처음 시작하면 1 초에 약 1000 개의 레코드가 될 것입니다. 시간이 진행됨에 따라 느려지고 느려지므로 지금 당장 180 초마다 약 1 행이됩니다.쿼리

함수의 일반 구문은 다음과 같습니다 구문 분석

function parse($file) { 
    $handle = fopen($file, 'r'); 
    while (!feof($handle)) { 
    $line = fgets($fileHandle, 1000); 
    switch (substr($line, 0, 2)) { //gets record type 
     case '01' : 
     //parse the record 
     //escapes some strings with mysql_real_escape_string() 
     mysql_query('INSERT INTO table VALUES ($a, $b, $c...'); 
     case '02' : 
     ... 
    } 
    } 
} 

현재 파일은 몇 만 개 기록을 가지고있다. 서버가 메모리 공간을 잃어 버리지 않는 것 같습니다. 프로세스가 느려질 수있는 원인을 아는 사람이 있습니까?

+0

테이블에 색인이 있습니까? 색인 업데이트가 원인 일 수 있습니다. 또한 얼마나 자주 저지르는가? –

+0

'테이블'에 대한 색인 생성이 있습니까? – bensiu

+1

@bensiu & @Jim Garrison - INSERT에 대한 인덱싱이 필요한 이유는 무엇입니까? – FeRtoll

답변

6

아마도 인덱스에 자주 쓰는 것과 관련이 있습니다. 당신은 나의 첫 번째 제안이 될 MyISAM을 이미 사용하고있다.

제안

  1. 일괄 삽입

    마다 100 개의 행
  2. 사용 INSERT MySQL은 삽입 신속하게 대기를 완료하고, MySQL은 자원을 더 허용하는 레코드를 삽입 할 수 있도록 허용하는 DELAYED.
  3. 은 스크립트, 당신은 FILE 오기 기능에도 사용하여로드 할 수있는 SQL 덤프/구분 된 파일을 만들
+0

고마워, 나는 이것들을 시도 할 것이다. 자동 증가 열에는 기본 키가 하나 뿐인 색인 만 있습니다. –

+0

@ParrisVarney - 당신이 준'INSERT'는'AUTO_INCREMENT'와 호환되지 않습니다! 'SHOW CREATE TABLE'을 제공해주세요. –

1

나는 당신이 훨씬 더 안전하기 때문에 PDO를 사용하는 것이 바람직 (이 속도 향상을 얻었다) 거래에서 쿼리를 실행 해해야한다고 생각합니다. PDO에서 prepared statement는 아마 SQL-injection에 취약하기 때문에 더 빠를 것이지만 적어도 더 안전 할 것입니다. 그렇게하면 훨씬 더 빠를 것입니다. 나는 당신을 위해 태그의 예를 준비 :

<?php 

$array = array(
    "ActionScript", 
    "AppleScript", 
    "Asp", 
    "BASIC", 
    "C", 
    "C++", 
    "Clojure", 
    "COBOL", 
    "ColdFusion", 
    "Erlang", 
    "Fortran", 
    "Groovy", 
    "Haskell", 
    "Java", 
    "JavaScript", 
    "Lisp", 
    "Perl", 
    "PHP", 
    "Python", 
    "Ruby", 
    "Scala", 
    "Scheme" 
); 

function createTable($db) { 
    $db->exec("CREATE TABLE IF NOT EXISTS tags (id INTEGER PRIMARY KEY, tag TEXT NOT NULL UNIQUE)"); 
} 

function insertData($db, $array) { 
    $db->beginTransaction(); 

    foreach($array as $elm) { 
     try { 
      $placeholder = array($elm); 
      $stmt = $db->prepare("INSERT INTO tags (tag) VALUES (?)"); 
      $stmt->execute($placeholder); 
     } catch(PDOException $e) { 
      /*** roll back the transaction if we fail ***/ 
      $db->rollback(); 
      /*** echo the sql statement and error message ***/ 
      echo $sql . '<br />' . $e->getMessage(); 
     } 
    } 

    $db->commit(); 
} 

$db = new PDO('sqlite:database/tags.sqlite3'); 
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); 
// 
createTable($db); 
insertData($db, $array); 

P.S : 나는 또한 InnoDB 아마 더 나은 될 것입니다 지적하고 싶습니다.

+0

MyISAM은 트랜잭션을 완전히 무시합니다. –

+0

나는 그것을 몰랐다! – Alfred

+0

데이터가 내부 피드에서오고 있으며 SQL 주입에 대해 걱정하지 않습니다. 나는 PHP의 버전이 PDO를 지원한다고 생각하지 않지만 업그레이드를 위해 제 경우에 탄약을 추가 할 수 있습니다. MySQL이 아직하지 않은 최적화를 수행합니까? –

3

당신은 아마이 테이블에 하나 개 이상의 인덱스가 배치 삽입보다 훨씬 빨라집니다 http://dev.mysql.com/doc/refman/5.1/en/load-data.html를 참조하게한다. 따라서 각 행은 갈수록 커지는 인덱스에 삽입됩니다. 당신이 당신의 부하를 시작하기 전에 당신이 완료 후,

ALTER TABLE 테이블 DISABLE 키

ALTER 표 테이블 키

에게 ENABLE

다시 사용 키가 오래 걸릴 수 있습니다.

당신이 그것을로드하는 동안 테이블을 사용하지 마십시오. 또한 INSERT DELAYED가 도움이 될 수 있습니다. 그러나 그렇지 않으면 조용한 데이터베이스 서버에서이 테이블로드를 수행하고있는 것은 아닙니다.