2014-10-21 8 views
0

페이지 히트 카운터에서 일하고 있습니다. 페이지 소유자는 웹 서버에 스크립트에 대한 링크가있는 작은 카운터 이미지를 페이지에 배치합니다. 누군가가 브라우저에서 페이지를 열면 내 스크립트가 호출되어 브라우저로 다시 보내지는 히트 번호의 이미지를 생성합니다. $ 페이지 ID에서 $ _SERVER [ 'REMOTE_ADDR'] — 시청자의 호스트의 IP : $PHP, MySQL : 하위 쿼리를 캐시 할 수 있습니까?

$ _SERVER [ 'HTTP_REFERER'] 내가 페이지 ID를 식별하기 위해 페이지의 URL을 얻을에서 IP, 고유 IP 만 계산하므로. 이 데이터는 표 조회수 (page_id, ip)에 수집됩니다. 그렇지 않으면,

$res1 = mysqli_query($DB, "SELECT ip FROM Hits WHERE page_id='$page_id'"); 
$number_of_hits = mysqli_num_rows($res1); 

가 지금은 새로 도착한 IP가 된 사람 가운데 나열되어 있는지 여부를 테스트 할 필요가 : 이전 히트 곡을 계산하기 위해

, 나는 주어진 페이지에 대한 저장된 IP의 수를 계산 나는 그것을 버리고 카운터를 증가시키지 않을 것이다. 이미 쿼리에 의해 발견 된 행을 루프를 실행하거나 다른 쿼리를 실행할 수 있습니다 :

$res2 = mysqli_query($DB, "SELECT ip FROM Hits WHERE page_id='$page_id' AND ip='$ip'"); 
$number_of_new_hit_occasions = mysqli_num_rows($res2); 
if($number_of_new_hit_occasions == 0) ++$number_of_hits; 

을하지만 두 번째 쿼리는 본질적으로 중복 등의 자원이 소요되는 첫 번째로,; 두 번째 테이블의 전체 테이블보다 첫 번째 쿼리에서 얻은 작은 결과를 검색하는 것이 훨씬 더 효율적입니다. 내가 말,라는 메모리에 가상 테이블의 첫 번째 쿼리를 저장할 수 있으면 좋겠다

, IPs_for_given_page은 (아마도 어떻게 든 $ RES1으로 함), 및

$res2 = mysqli_query($DB, "SELECT ip FROM IPs_for_given_page WHERE ip='$ip'"); 
$number_of_new_hit_occasions = mysqli_num_rows($res2); 

에 두 번째 쿼리를 감소 어떤 방법으로도 가능합니까?

+0

'mysqli_num_rows를 사용하지 마십시오. @OllieJones가 말한대로'COUNT'을 사용하면 더 효율적입니다. – Sal00m

답변

1

언급 한대로 결과를 캐시 할 수있는 방법이 없습니다. 그러나 당신이하려는 일을하는보다 효율적인 방법이 있습니다.

행을 계산하려면이 종류의 쿼리를 사용하고 1 행 결과 집합을 검색하십시오. 결과 집합의 행을 계산하는 것보다 훨씬 빠릅니다.

SELECT COUNT(*) FROM Hits WHERE page_id=<<whatever>> 

당신은 두 가지를 수행하여 IP 번호의 중복 제거를 자동화 할 수 있습니다 :

먼저, (page_id,ip)에 화합물 고유 인덱스를 만들 수 있습니다.

둘째,이 SQL 문을 사용하여 적중 행을 삽입하십시오.

INSERT IGNORE INTO Hits (page_id, ip) VALUES (<<whatever>>, <<whatever>>) 

IGNORE 절과 결합 된 고유 인덱스

함께 동일한 IP 주소에 대한 중복 히트 행을 받아들이에서 MySQL을 방지한다.

내가 제안한 복합 색인은 COUNT 쿼리를 가속화합니다.

+0

많은 조언을 주셔서 감사 드리며, 아마도 이것이 최선의 방법 일 것입니다.하지만 제 질문은 아닙니다. 긍정 응답 : 'CREATE TEMPORARY TABLE IPs_for_given_page AS (SELECT IP FROM where page_id = '$ page_id'); '? –

관련 문제