2013-04-17 2 views
0

내 코드에 문제가 있습니다. 데이터베이스에 연결하는 코드입니다.이 고유 데이터를 다른 테이블에서 선택하고, 내 코드에 아무런 문제가 없습니다. 알았어.하지만 쿼리하는 데 너무 오랜 시간이 걸린다.내 경우에 SQL 실행 속도가 느림

<?php 
include "koneksi.php"; 

$no=1; 
$arqury=odbc_exec($koneksi, "SELECT DISTINCT NIP_AR,NAMA_AR FROM USRBPS.MASTERFILE"); 
while($ar=odbc_fetch_array($arqury)){ 
    $total=0; 
    $ambilqury=odbc_exec($koneksi, "SELECT NPWP FROM USRBPS.MASTERFILE WHERE NIP_AR='$ar[NIP_AR]'"); 
    while($ambil=odbc_fetch_array($ambilqury)){ 
     $testqury=mysql_query("SELECT SUM(jumlah_bayar) as PENERIMAAN FROM mpnruteng WHERE npwp='$ambil[NPWP]'"); 
     $test=mysql_fetch_array($testqury); 
     $total += $test[PENERIMAAN]; 
    } 

    if($ar[NIP_AR]==""){ 
     echo "<tr><td>$no</td><td colspan=2>UNASSIGN</td><td>$total</td>"; 
    } 
    else{ 
     echo "<tr><td>$no</td><td>$ar[NAMA_AR]</td><td>$ar[NIP_AR]</td><td>$total</td></tr>"; 
    } 
    $no++; 
} 

?> 

간단하게 다음과 같이되고있는에,

|Name |num_se 
--------------- 
|andre |1111 
|john |2222 
|simon |3333 
|andre |4444 
|andre |5555 
|simon |6666 
|john |7777 


|num_se |Total 
--------------- 
|1111 |12 
|2222 |15 
|3333 |10 
|4444 |8 
|5555 |20 
|6666 |18 
|7777 |22 

그래서, 내가 필요한 것은 각각의 '이름'에서 '전체'의 합계를 얻을 수있다. 내가 얻고 싶은 것은 num_se에서 얻는 "합계"의 각 합계로 "고유"(이 예에서는 Andre, John 및 Simon)라는 이름의 목록입니다.

죄송합니다. 제 영어는 좋지 않지만 이해하길 바랍니다.

+0

인덱스가 필요하지 않을 수도 있고 루핑 대신 조인을 사용하는 것이 좋습니다. –

+0

다른 데이터베이스로 작업 하시겠습니까? 당신이하지 않는 경우에 당신은 당신의 SQL을 하나의 쿼리 문으로 결합 할 수 있습니다. 이것은 최적화 된 db 엔진으로부터 큰 이익을 얻을 것입니다. 적어도 SELECT NIP_AR, NAMA_AR, NPWP FROM USRBPS.MASTERFILE ORDER BY NIP_AR'을 반복합니다. – collapsar

답변

0

Windows 사용자 인 경우 127.0.0.1 대신 localhost를 사용하면 데이터베이스 연결 속도가 느려집니다. 만약 내가 제대로 이해하고

+0

어떻게됩니까? –

+0

@Sylvain Fabre : I localhost를 이미 사용하고 있지만 여전히 느리다. – DymasSedhayu

+0

그러면 호스트 파일이나 DNS 구성이 어리석은 일이 있습니다. – Sepster

1

,이 쿼리는

SELECT t1.Name, sum(t2.Total) 
FROM (table1 t1 LEFT JOIN table2 t2 ON t1.num_se = t2.num_se) 
GROUP BY t1.Name 

이 경우에 따라 테이블 이름과 열 이름을 수정하는 데 도움이 될 수 있습니다. 두 개의 분리 된 데이터 소스를 사용하는 이유

업데이트

모르겠어요. 그러나이 접근 방식이 코드의 효율성을 향상시킬 것이라고 생각합니다.

첫째,이 쿼리에 의해 각 name에 속하는 모든 num_se의 목록을 얻을 :

"SELECT Name, GROUP_CONCAT(num_se) as nums FROM table1 GROUP BY Name" 

이 이제 결과 배열 ('$ 아칸소')가 키 nums

으로이 "1111,2222" 같은 요소가됩니다

둘째, 각 name

"SELECT SUM(Total) as total FROM Table2 WHERE num_se IN (" . $ar['nums'] . ")" 

의 합계를 얻기 위해이 쿼리를 사용 그리고 당신은 얻을 것이다 각 name에 대한 total은 두 번째 루프가 필요하지 않습니다.

쿼리가 안전한지 확인하기 위해 이스케이프 기술을 사용해야합니다.

+0

하지만 내가 가지고있는 2 테이블은 데이터베이스의 2 가지 다른 유형에서오고있어 문제가 생겼다. MySQL 데이터베이스의 첫 번째 테이블은 다른 하나는 ODBC Oracle 데이터베이스이다. Apache 웹 서버 appserv를 사용 중입니다. – DymasSedhayu

+0

네, 제 대답을 업데이트했습니다. 시도해 볼 수 있습니다. –

0

어떤 해결책을 제시하기 전에 쿼리가 너무 느린 이유를 설명하고자했습니다. 코드를 신중하게 보면 첫 번째 쿼리 결과에 도달 레코드에 대한 데이터베이스 연결이 열리고 있습니다. 주요 비용은 데이터베이스에 대해 쿼리를 열고 실행하는 것입니다. 첫 번째 결과에 1000 개의 레코드가 있다면 상상해보십시오. 데이터베이스 연결을 1000 번 열면 매우 느려질 것입니다. Trung에서 설명한대로 내부 조인 또는 하위 쿼리를 사용합니다. 또는 저장 프로 시저를 사용하고 SP 내부에 논리를 배치하는 것이 가능하지 않은 경우 성능을 얻는 데 도움이됩니다. 저장 프로 시저를 만들고 쉼표로 구분 된 입력 매개 변수를 다른 ID에서 전달합니다. 다른 데이터베이스에서 가져온 항목을 ID로 사용합니다. SP 내부에서 쉼표 Ids를 루프로 분리하고 select 문을 수행합니다. 임시 테이블을 사용하여 그렇게 할 수 있습니다. 장점은 데이터베이스 연결을 한 번만 여는 것입니다.

+0

하지만 내가 가지고있는 2 테이블은 데이터베이스의 2 가지 다른 유형에서오고있어 문제가 생겼다. MySQL 데이터베이스의 첫 번째 테이블은 다른 하나는 ODBC Oracle 데이터베이스이다. Apache 웹 서버 appserv를 사용 중입니다. 하지만이 두 가지 유형의 데이터베이스에 가입하는 방법을 알고 있다면 좋을 것입니다. 저는 마지막 솔루션 "저장 프로 시저를 사용하고 SP 내부에 로직을 넣는 것"에 흥미 롭습니다.하지만 이해가 안됩니다. 제게 설명해 주시겠습니까? – DymasSedhayu

+0

내 솔루션을 업데이트했습니다. 나는 당신이 mySQL http://www.mysqltutorial.org/mysql-stored-procedure-tutorial.aspx에 저장 프로 시저를 생성하는 방법을 알고 있기를 희망한다. – Devesh

1

앞에서 두 개의 개별 데이터 소스에 대해 작업하고 있다고 설명하는 것이 적절했을 것입니다.

PHP에서 결과 집합을 반복하여 개별 쿼리를 호출하여 다른 테이블의 단일 행을 반환하기 때문에 속도가 매우 느립니다. 이는 매우 비효율적입니다.

데이터베이스가 JOIN을 사용하여 두 개의 관련 테이블 간의 관계를 처리하도록 한 다음 개별 합계가 아닌 총계의 집계를 처리하도록합니다.

다음 쿼리는 nip_ar 및 nama_ar 각각 별개의 쌍에 대한 총 얻을 것이다 :

SELECT 
    t1.NIP_AR, 
    t1.NAMA_AR, 
    SUM(t2.jumlah_bayar) as PENERIMAAN 

FROM 
    USRBPS.MASTERFILE t1 

    INNER JOIN mpnruteng t2 
    ON t2.npwp = t1.npwp 

GROUP BY 
    1, 2 

을하지만 당신은 어쨌든 하나 그랜드 $total에이를 압연하고, 그래서 이것은 당신을 위해 얻을 것이다 :

SELECT 
    SUM(PENERIMAAN) as PENERIMAAN 

FROM 
    (
    SELECT 
     t1.NIP_AR, 
     t1.NAMA_AR, 
     SUM(t2.jumlah_bayar) as PENERIMAAN 

    FROM 
     USRBPS.MASTERFILE t1 

     INNER JOIN mpnruteng t2 
     ON t2.npwp = t1.npwp 

    GROUP BY 
     1, 2 
) 

Oracles 서버에서 mySql 서버에 대한 링크를 구성 할 수 있습니다. Using Heterogenous Service Agents - chapter 4. Setting up access to non-Oracle systems을 참조하십시오. 내 이해는 당신이 mySql에서 오라클에 연결할 수 없다는 것입니다.

이렇게하면 Oracle 인스턴스에서 위 쿼리를 실행할 수 있습니다. 데이터 소스 이름을 사용하여 테이블 이름을 완전히 한정하려면 테이블 이름을 업데이트해야합니다.

+0

같은 연결에서 데이터베이스를 얻었 으면 좋지만 데이터베이스를 얻는다. 다른 연결 때문에 내 내부 조인을 사용할 수 없습니다. 다른 하나는 odbc_conect 을 사용하고 다른 암호와 사용자 이름은 모두 – DymasSedhayu

+0

이며 데이터베이스 쿼리의 형식은이 둘 사이에서 다릅니다. mysql은 "mysql_query (쿼리)"를 사용하지만, "odbc_exec (연결, 쿼리)"를 사용하는 odbc. 그래서 나는 그 두 데이터가 INNER JOIN을 사용할 수 있다고 생각하지 않는다. 그러나 나에게 잘못을 말하고 바로 잡으십시오. – DymasSedhayu

+0

@DymasSedhayu 서로 다른 두 개의 DBMS를 함께 연결하는 방법을 설명하는 문서를 읽었습니까? – Sepster

관련 문제