2013-05-01 1 views
3

400k 레코드 (only ...)가있는 InnoDb item 테이블에 쿼리가 있습니다. 프리젠 테이션 레이어 (페이지 당 60)에 대한 결과를 페이지화해야하므로 LIMIT에 표시 할 페이지에 따라 값을 사용합니다.MySQL LIMIT x, y 퍼포먼스 2 머신에서 큰 차이

쿼리합니다 (110000 오프셋 그냥 예입니다)입니다 :

SELECT i.id, sale_type, property_type, title, property_name, latitude, 
     longitude,street_number, street_name, post_code,picture, url, 
     score, dw_id, post_date 
FROM item i WHERE picture IS NOT NULL AND picture != '' 
AND sale_type = 0 
ORDER BY score DESC LIMIT 110000, 60; 

내 컴퓨터에서이 쿼리를 실행하면 1 초 정도 걸립니다. 테스트 서버에서이 쿼리를 실행하는 데 45-50 초가 걸립니다.

EXPLAIN은 모두 동일하다 : 쿼리 show variables

+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+ 
| 1 | SIMPLE  | i  | index | NULL   | IDX_SCORE | 5  | NULL | 110060 | Using where | 
+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+ 

유일한 구성 차이 :

  • innodb_use_native_aio. 내 컴퓨터가 아닌 테스트 서버에서 사용할 수 있습니다.

    • mysqld에 : 나는 그것을 해제 시도 내가 테스트 서버에 어떤 큰 변화를
    • innodb_buffer_pool_size 1G 표시되지 않는, 2G 내 컴퓨터에

    테스트 서버는 2GB의 RAM, 2 코어 CPU는있다 아무도 위의 쿼리를 실행하지 동안 모든 시간에 RAM의> 65 %를 사용하지만 쿼리 위의 실행 1 ~ 2 % 증가

  • mysqld에는 CPU의 14 %를 사용하는 경우 유휴

내 로컬 컴퓨터는 8GB의 8 코어 CPU가 있습니다

  • mysqld가 모든 시간에 RAM의 28 %를 사용하고, 위의 쿼리를 실행하는 동안 정말 증가하지 않는 (또는 그렇게 짧은 시간 동안 나는 그것을 볼 수 있습니다) 위의 쿼리를 실행하는 동안
  • mysqld를가 없음을 CPU의 48 %를 사용하지 않을 때 유휴

내가 테스트 서버에서 동일한 성능을 위해 무엇을 할 수 있습니까? RAM 및/또는 CPU가 너무 낮습니까?

UPDATE

는 내 컴퓨터와 비슷한 값에 뛰어 내가 설정 RAM, 4 코어 CPU와 성능의 동일 사양하지만 8 세대로 새로운 테스트 서버있다. 원래 서버가 모든 RAM/CPU를 사용하지 않는 것 같습니다. 왜 성능이 그렇게 나 빠졌습니까?

+1

빌은 꽤 잘 대답했다고 생각하지만, 그 외에도'picture' 컬럼이'NULL' 또는''''(공백)이되지 않게하는 것이 훨씬 낫다고 생각합니다. 입력하는 동안 비어 있으면 'NULL'로 설정하고 위의 'AND'를 수행하지 않아야합니다. – pickypg

+0

@pickypg 고마워요. 생각해 봤어야 할 훌륭한 아이디어입니다. 우리 코드에서 쉽게 할 수 있습니다. – JScoobyCed

답변

2

성능을 저하시키는 가장 확실한 방법 중 하나는 MySQL이 메모리에 맞지 않는 인덱스를 스캔하는 것입니다. 따라서 쿼리 중에 인덱스의 일부를 버퍼 풀로로드 한 다음 해당 부분을 제거하고 인덱스의 다른 부분을로드해야합니다. 쿼리하는 동안 이와 같이 버퍼 풀에서 변동이 발생하면 많은 I/O로드가 발생하게되어 매우 느려집니다. 디스크 I/O는 RAM보다 약 10 만 배 정도 느립니다.

인덱스가 1.5GB라면 버퍼 풀 1GB와 버퍼 풀 2GB 사이에는 큰 차이가 있습니다.

또 다른 팁 : 실제로는 LIMIT 110000, 60을 사용하고 싶지 않습니다.이로 인해 MySQL은 버퍼 풀에서 110000 개의 행을 읽습니다 (필요할 경우 디스크에서로드 할 수 있음). 결과 집합을 훨씬 더 효율적으로 페이징하는 다른 방법이 있습니다.

Optimized Pagination using MySQL과 같은 기사를 참조하십시오.

+0

감사합니다. 링크에 대해 자세히 설명 하겠지만 처음에는 정적 SQL을 사용하는 것으로 보입니다. 내 위의 SQL은 너무 많은 중 하나입니다 (SQL은 많은 옵션이있는 검색 양식 용이며 일부는 값의 범위 임) ... 처음 보면 :) – JScoobyCed