2010-05-26 2 views
1

$ res에는 약 488k 행이 포함되어있어 전체 루프에는 61 초가 걸립니다! 1 사이클 당 1.25ms가 넘습니다! 그 시간 동안 무엇을하고 있습니까?mysql 결과 집합의 속도가 느린 이유는 무엇입니까? (사이클 당 1.4ms)

while($row = $res->fetch_assoc()) 
{ 
    $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]['std'] = $row['cost_std']; 
    $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]['ecn'] = $row['cost_ecn']; 
    $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]['wnd'] = $row['cost_wnd']; 
    $dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']]['other_destination'] = $row['destination_id']; 
    $dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']]['carrier_destination'] = $row['carrier_destination_id']; 
} 

이제 10 개 행, 더 작은 어레이 및 성능이 30 배 이상 (0.041ms) 빠르지 만 더 나은 결과는 아닙니다.

while($row = $res->fetch_assoc()) 
{ 
    $customer[$row['id']]['name'] = $row['name']; 
    $customer[$row['id']]['code'] = $row['customer']; 
} 
+1

당신이 메모리에 모든 결과를로드해야합니까? –

+0

61 초의 488k 행은 실제로 반복마다 0.125ms이므로 30 초가 아니라 3 배 느립니다. * 길을 너무 오랫동안 보면서 그 숫자가 옳지 않다고 생각하여 확인하기가 어려웠습니다! :) – Chris

답변

2

큰 배열은 메모리를 할당하고 처리하는 데 더 많은 시간이 걸립니다. 따라서 우리는 항상 데이터베이스에 모든 작업을 수행하고 최종 결과로 10 개의 행을 반환하도록 요청하는 것입니다.

+0

나는 우리가 ** 게으른 ** 때문에 단지라고 생각했다 ** –

+0

고마워. 속도를 낼 방법이 없나요? 그것은 웹 응용 프로그램이 아니지만 많은 데이터를 망쳐 놓은 작은 PHP 데몬입니다. 그래서 기다릴 수는 있지만 100 % CPU에서의 순간은 조금 극단적이며 결과는 최소 10 배 증가 할 것입니다. – pawpro

+0

데이터베이스에서 가능한 모든 작업을 수행하십시오. 항상 * 작성하는 코드보다 빠릅니다. 그리고 작성해야하는 코드가 적어집니다. –

0

I 의심의 모든 시간을내어 무엇을하는 치수의 일부 (또는 전부가?) 문자열 필드에서 키가되고있는 4 차원 배열, 자신이 $row에서 추출하는 데 그 가치에 대한 지속적인 액세스입니다 ...

나는 재고 심각하게 당신을 건의 할 것입니다 :

  1. 을 당신이 최고의 데이터 구조는 최적의 액세스
  2. 이 될 것입니다 무슨 메모리
  3. 그렇다면 모든 것을해야하는지 여부
1

488k는 행이 많아 많은 데이터를 의미합니다. 배열에 고정하는 항목이 많을수록 할당 할 수있는 메모리가 많아지고 요소를 조회하는 데 더 오래 걸립니다.

거의 50 만 번 동일한 코드를 실행하고, 그것은 배열을 최적화 가치가있을 거라고는 액세스 :

... { 
    $myclist =& $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]; 
    $myclist['std'] = $row['..']; 
    $myclist['ecn'] = $row['..']; 
    ... 
    $dest =& $dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']]; 
    $dest['..'] = $row['..']; 
    $dest['..'] = $row['..']; 
} 

만 반복적으로 배열 조회를하고 한 번 대신하고 그런 식으로, 런타임을 크게 단축 할 수 있습니다. 배열에 많은 것들을 붙이는 것은 관계없이 빠르지는 않을 것입니다.

장기적으로 데이터를 데이터베이스에 두는 것이 가장 좋습니다. 필요에 따라 데이터를 가져 와서 (또는 데이터베이스의 크기를 합산/평균/뭐든간에). 이것에 대해

+0

감사.데이터베이스에서 무작위로 높은 비율의 데이터가 필요하기 때문에 500q/s 이상의 속도로 처리하기 위해 연속적으로 데이터를 처리해야하므로 데이터베이스에 부담을주지 않기를 바라고 있습니다. db에 예측할 수없는로드가 발생합니다. 나는 그것을 가지고 놀 것이다. 최악의 경우 나는 memcached를 시도 할 것이다 :) – pawpro

0

무엇 :

$cache = array(); 
while($row = $res->fetch_assoc()) 
{ 
    $key = $row['upload_id']."\n".$row['dialcode_id']."\n".$row['carrier_id']; 
    $key1 = "1\n$key"; 
    if (!array_key_exists($key1, $cache)) 
     $cache[$key1] = &$clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]; 

    $ref = &$cache[$key1]; 
    $ref['std'] = $row['cost_std']; 
    $ref['ecn'] = $row['cost_ecn']; 
    $ref['wnd'] = $row['cost_wnd']; 

    $key2 = "2\n$key"; 
    if (!array_key_exists($key2, $cache)) 
     $cache[$key2] = &$dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']] 

    $ref = &$cache[$key2]; 
    $ref['other_destination'] = $row['destination_id']; 
    $ref['carrier_destination'] = $row['carrier_destination_id']; 
} 
+0

나는 이것으로 어디로 가는지 알게된다. 좋은데, 나는 처음에 memcached에게 줄 것이다. :) – pawpro

+0

@pawpro : memcached는 배열 자체로 색인하기. 루프에서 많은 동등한 조회를 수행하기 때문에 memcached 기반 솔루션조차도이 접근 방식의 이점을 누릴 수 있습니다. – Tomalak

+0

나는 relize를하지만,이 데이터의 <1 %만이 정규 사용 상태에있을 것으로 기대한다. 따라서 memcached를 사용하여 캐시하는 것이 합리적입니다 (db 쿼리 캐시는 테이블이 변경 될 때 높은 캐시 실패율을 초래하지만 기존 데이터는 변경하지 않습니다) – pawpro