2011-12-06 3 views
0

사용자 정보가있는 테이블과 GeolIP 데이터베이스의 Geolocation 데이터가있는 테이블 간의 상호 참조에 문제가 있습니다.IP 정보 용 하위 쿼리 및 인덱싱

사용자 테이블에 정수가 아닌 표준 형식의 IP 주소와 GeoIP 테이블의 GeoIP 데이터가 정수 IP 범위를 갖습니다.

이 쿼리는 작동하지만 매우 느리고 최적화되지 않았습니다.

SELECT email, country 
FROM users 
INNER JOIN geoip ON users.ip BETWEEN geoip.startip AND geoip.endip 

나는 여기에서 아주 쉽게 뭔가를 잃어버린 것처럼 느낍니다.

업데이트 :이 쿼리는 작동하지만 매우 느립니다. 인덱싱 할 수있는 방법이 있습니까? 지금 당장 실행될 때마다 각 행은 실행하는 데 약 300-500ms가 걸릴 것이고 이는 너무 느립니다.

SELECT email, country 
FROM users INNER JOIN geoip ON INET_ATON(users.ip) 
BETWEEN geoip.startip AND geoip.endip 

고마워요!

UPDATE 2 : 다음은 쿼리에 EXPLAIN 출력입니다 : 내가 지금 정수 전용 IP 행을 추가 할 수 없습니다

+----+-------------+-----------+------+---------------+------+---------+------+----------+-------------+ 
| id | select_type | table  | type | possible_keys | key | key_len | ref | rows  | Extra  | 
+----+-------------+-----------+------+---------------+------+---------+------+----------+-------------+ 
| 1 | SIMPLE  | geoip  | ALL | NULL   | NULL | NULL | NULL | 3651972 |    | 
| 1 | SIMPLE  | users  | ALL | NULL   | NULL | NULL | NULL | 87996123 | Using where | 
+----+-------------+-----------+------+---------------+------+---------+------+----------+-------------+ 

DB를의 사용과는 만 90 행 왜냐하면; 그것은 어떤 중단 시간 동안하는 일을 들여다 볼 것이지만, 지금 당장이 방법으로 실행하고 싶습니다.

답변

2

나는 아직, 그래서 여기에 언급 할 수없는 '답변'의 ...

당신은 작동 확실 해요? 설명을 올바르게 이해하면 char 또는 varchar에 CIDR 표기법으로 users.ip이 있고 정수로 geoip.startip/endip이 있습니다. 따라서이 쿼리는이 두 쿼리를 올바르게 비교할 방법이 없습니다. 이 일을

올바른 방법은 어느 것이

SELECT email, country 
FROM users INNER JOIN geoip ON INET_ATON(users.ip) 
BETWEEN geoip.startip AND geoip.endip 

또는 꽤 많이있는 테이블이 큰 (더 행)입니다 따라 하나 더

SELECT email, country 
FROM users INNER JOIN geoip ON users.ip 
BETWEEN INET_NTOA(geoip.startip) AND INET_NTOA(geoip.endip) 

.

그러나 이것을 수행하는 가장 좋은 방법은 users.ip을 정수 (또는 정수 해석이있는 다른 열)로 저장하는 것입니다.

+0

첫 번째 쿼리가 작동하지만 속도가 매우 느립니다. 인덱싱 할 수있는 방법이 있습니까? 지금 당장은 행마다 최소 300-500ms가 걸립니다. –

+0

geoip.startip 및 geoip.endip에 대한 색인이 있습니까? – Fox

+0

예, 시작점, 끝내기 및 국가에 대한 색인입니다. –