2010-02-13 6 views
2

$의 고해상도 (배열) -> (카운트 50()!) 예 :MySQL의 쿼리 최적화

(
    [1] => Array 
     (
      [artistname] => Lady GaGa 
      [songname] => Love Games 
      [duration] => 3:31 
      [url] => 7e91a5ca16ae 
      [server] => 3 
     ) 

    [2] => Array 
     (
      [artistname] => DJ Layla 
      [songname] => Single Lady 
      [duration] => 3:20 
      [url] => f0906a3087eb 
      [server] => 3 
     ) 

    [3] => Array 
     (
      [artistname] => Lady Gaga 
      [songname] => Bad Romance (Bimbo Jones Clean Radio Remix) 
      [duration] => 3:59 
      [url] => 36e77d5a80357 
      [server] => 3 
     ) 
} 

PHP 코드 :

$massquery = ''; 
foreach($res as $value) 
{ 
    if(!get_magic_quotes_gpc()) 
    { 
     $value['artistname'] = mysql_escape_string($value['artistname']); 
     $value['songname']  = mysql_escape_string($value['songname']); 
     $value['duration']  = mysql_escape_string($value['duration']); 
     $value['url']   = mysql_escape_string($value['url']); 
     $value['server']  = mysql_escape_string($value['server']); 
    } 

    $value['artistname'] = trim($value['artistname']); 
    $value['songname']  = trim($value['songname']); 
    $value['duration']  = trim($value['duration']); 
    $value['url']   = trim($value['url']); 
    $value['server']  = trim($value['server']); 

    $sh  = mysql_query("SELECT `artistname`,`songname`,`server` FROM `music` WHERE `artistname`='".$value['artistname']."' AMD `songname`='".$value['songname']."' AND `server`='".$value['server']."' LIMIT 1"); 
    if(!mysql_num_rows($sh)) 
    { 
     $massquery .= '("'.$value['artistname'].'", "'.$value['songname'].'", "'.$value['duration'].'", "'.$value['url'].'", "'.$value['server'].'"),'; 
    } 
} 

if(!empty($massquery)) 
{ 
    $massquery = substr($massquery, 0, -1); 
    $query  = mysql_query('INSERT INTO `music` (`artistname`, `songname`, `duration`, `url`, `server`) VALUES '.$massquery); 
} 
mysql_close($mysql); 

그것은 "SELECT"(50 개)에 요구에 밝혀 아주 나쁜 데이터베이스 = ( 어떻게이 코드를 최적화 할 수 있습니다

답변에서 :

CREATE TABLE `music` (
    `id` int(50) NOT NULL auto_increment, 
    `artistname` varchar(50) NOT NULL, 
    `songname` varchar(50) NOT NULL, 
    `duration` varchar(6) NOT NULL, 
    `url` varchar(255) NOT NULL, 
    `server` int(5) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `artistname` (`artistname`,`songname`,`server`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

INSERT INTO `music` VALUES ('test', 'btest', 1); 

...

SELECT `artistname` , `songname` , `server` 
FROM `music` 
WHERE FALSE 
OR (
`artistname` = 'test' 
AND `songname` = 'btest' 
AND `server` = '1' 
) 
OR (
`artistname` = 'sas' 
AND `songname` = 'asf' 
AND `server` = '1' 
) 
LIMIT 0 , 30 

어떻게 데이터베이스에 아직없는 그 노래를 삽입합니까? 불량 영어로 죄송합니다

답변

1

튜플 (아티스트 이름, 노래 이름, 서버)이있는 다른 레코드가없는 경우에만 새 레코드를 삽입하고 싶습니다.
이 세 필드에 대해 create a unique index 인 경우 MySQL은 이중 복사를 삽입하지 않습니다. 그럼 당신은

INSERT IGNORE INTO 
    tablename 
    (a,b,c,x,y,z) 
VALUES 
    (1,2,3,4,5,6), 
    (7,8,9,10,11,12), 
    ... 
    (95,96,97,98,99,100) 

또는 prepared statement, 예를 들어, 같은 것을 사용 할 수 있습니다

$pdo = new PDO("mysql:host=localhost;dbname=test", 'localonly', 'localonly'); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

/* test table */ 
$pdo->exec(' 
    CREATE TEMPORARY TABLE foo (
     id int auto_increment, 
     artistname varchar(64) not null, 
     songname varchar(64) not null, 
     duration varchar(16) not null, 
     url varchar(64) not null, 
     server int not null, 
     primary key(id), 
     unique key (artistname,songname,server) 
    ) 
'); 

$data = array(
    array(':artistname' => 'Lady GaGa', ':songname' => 'Love Games', ':duration' => '3:31', ':url' => '7e91a5ca16ae', ':server' => 3), 
    array(':artistname' => 'DJ Layla', ':songname' => 'Single Lady', ':duration' => '3:20', ':url' => 'f0906a3087eb', ':server' => 3), 
    array(':artistname' => 'Lady Gaga', ':songname' => 'Bad Romance (Bimbo Jones Clean Radio Remix)', ':duration' => '3:59', ':url' => '36e77d5a80357', ':server' => 3) 
); 


/* the "actual" test script */ 
$stmt = $pdo->prepare(' 
    INSERT IGNORE INTO 
     foo 
     (duration, artistname, songname, server, url) 
    VALUES 
     (:duration, :artistname, :songname, :server, :url) 
'); 
// first run, all three records should be inserted 
foreach($data as $params) { 
    $stmt->execute($params); 
} 

// second run 
// same artist/songname, different server 
$newData = $data[0]; $newData[':server'] = 4; 
$data[] = $newData; 
// and a completly new record 
$data[] = array(':artistname' => 'xyz', ':songname' => 'The ABC song', ':duration' => '2:31', ':url' => 'whatever', ':server' => 2); 
// again insert all records (including the three that have already been inserted) 
foreach($data as $params) { 
    $stmt->execute($params); 
} 

/* fetch all records */ 
foreach($pdo->query('SELECT * FROM foo', PDO::FETCH_NUM) as $row) { 
    echo join(', ', $row), "\n"; 
} 

인쇄

1, Lady GaGa, Love Games, 3:31, 7e91a5ca16ae, 3 
2, DJ Layla, Single Lady, 3:20, f0906a3087eb, 3 
3, Lady Gaga, Bad Romance (Bimbo Jones Clean Radio Remix), 3:59, 36e77d5a80357, 3 
4, Lady GaGa, Love Games, 3:31, 7e91a5ca16ae, 4 
5, xyz, The ABC song, 2:31, whatever, 2 

처음 세 개의 기록

이 중복되지 않았다.

1

하나의이 같은 모든 관련 경우에 선택하고, PHP를 이용하여 결과를 확인 만들기 :

$sh = "SELECT `artistname`,`songname`,`server` FROM `music` WHERE "; 
$pq = "" 
foreach($res as $value) 
{ 
if(!get_magic_quotes_gpc()) 
{ 
    $value['artistname'] = mysql_escape_string($value['artistname']); 
    $value['songname']  = mysql_escape_string($value['songname']); 
    $value['duration']  = mysql_escape_string($value['duration']); 
    $value['url']   = mysql_escape_string($value['url']); 
    $value['server']  = mysql_escape_string($value['server']); 
} 

$value['artistname'] = trim($value['artistname']); 
$value['songname']  = trim($value['songname']); 
$value['duration']  = trim($value['duration']); 
$value['url']   = trim($value['url']); 
$value['server']  = trim($value['server']); 

$sh .= $pq . `(artistname`='".$value['artistname']."' AMD `songname`='".$value['songname']."' AND `server`='".$value['server']."')"); 
$pq = " OR "; 
} 

$res = mysql_query($sh); 
1

당신이 쓴 선택 쿼리는 foreach는 내부, 또는 할 수 물론 그것은 ' 매번 쿼리 할 것이다. $ res를 긴 WHERE 절에 넣으십시오.

$sql = "SELECT `artistname`,`songname`,`server` FROM `music` WHERE FALSE "; 
foreach($res as $value) 
{ 
    // ... 

    $sql .= "OR (`artistname`='".$value['artistname']."' AND `songname`='".$value['songname']."' AND `server`='".$value['server'].")"; 
} 

그런 다음 해당 데이터베이스에 대해 해당 쿼리를 실행하고 INSERT 쿼리를 작성하십시오.

+0

하는' 을 music' FROM artistname'''songname''server' 을 선택 WHERE FALSE OR 'btest'( artistname' '='검사 'AND' songname' = server' AND '=' 1 ' ) OR ( artistname''= 'SAS'가 'songname' AND ='ASF ' server' AND'= '1' ) LIMIT 0, 30 는 CREATE TABLE을'music' ( ' id' int (50) NOT NULL auto_increment, 'artistname' varchar (50) NOT NULL, 'songname' var char (50) NOT NULL, 'duration' varchar (6) NOT NULL, 'server' int (5) NOT NULL, PRIMARY KEY ('id') ) ENGINE = MyISAM DEFAULT CHARSET = utf8; INSERT INTO'음악 'VALUES ('test ','btest ', 1); 아직 데이터베이스에없는 노래는 어떻게 삽입합니까? – Isis