2012-07-31 2 views
6

어떤 방법이나 방법의 혼합이 가장 빠른 수행 상황?성능 및 정렬, 그리고 고유 한 mysql과 PHP 사이의 고유

$year = db_get_fields("select distinct year from car_cache order by year desc"); 

또는 내가 MySQL을 별개의 들었어요

$year = db_get_fields("select year from car_cache"); 
$year = array_unique($year); 
sort($year); 

큰 쿼리를위한 진짜 큰 성능 저하이며,이 테이블은 백만 행 이상을 가질 수 있습니다. Innodb이나 MyISAM과 같은 데이터베이스 유형의 조합이 가장 잘 작동하는지 궁금합니다. 많은 최적화가 매우 쿼리에 의존한다는 것을 알고 있습니다. 연도는 부호없는 숫자이지만 다른 필드는 다른 길이의 varchar이므로 차이를 만들 수도 있습니다. 예를 들면 다음과 같습니다 :

새로운 innodb 다중 키 방법을 사용하면이 같은 쿼리를 매우 빠르게 만들 수 있습니다. 그러나 별개의 명령은 제게 적기입니다.

답변

4

가능한 한 많은 작업을 MySQL에하십시오. 실행중인 쿼리가 효율적이지 않은 경우 실행하려는 쿼리의 올바른 인덱싱인지 또는 정렬 버퍼를 사용하는 설정인지에 관계없이 올바르게 설정되지 않을 가능성이 높습니다.

year 열에 색인이있는 경우 DISTINCT을 사용하는 것이 효율적이어야합니다. 그렇지 않으면 별개의 행을 페치하기 위해 전체 테이블 스캔이 필요합니다. MySQL이 아닌 PHP에서 별개의 행을 정렬하려고하면 MySQL에서 PHP로 더 많은 데이터를 (잠재적으로) 전송하고, PHP는 중복을 제거하기 전에 모든 데이터를 저장하는 데 훨씬 많은 메모리를 사용합니다.

다음은 내가 가진 dev 데이터베이스의 출력 예입니다. 또한이 데이터베이스는 쿼리가 실행되는 네트워크의 다른 서버에 있습니다.

SELECT COUNT(SerialNumber) FROM `readings`; 
> 97698592 

SELECT SQL_NO_CACHE DISTINCT `SerialNumber` 
FROM `readings` 
ORDER BY `SerialNumber` DESC 
LIMIT 10000; 
> Fetched 10000 records. Duration: 0.801 sec, fetched in: 0.082 sec 

> EXPLAIN *above_query* 
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra              | 
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+ 
| 1 | SIMPLE  | readings | range | NULL   | PRIMARY | 18  | NULL | 19 | Using index for group-by; Using temporary; Using filesort | 
+----+-------------+----------+-------+---------------+---------+---------+------+------+-----------------------------------------------------------+ 

, 비 인덱스입니다 다음은 MySQL이 모든 97,000,000 행을 검사하기 때문에 실행하는 데 영원히 소요 하나를 사용하여 SerialNumber 열 교환을 제외하고 내가 같은 쿼리를 시도하는 경우.

효율성의 일부는 돌아올 것으로 예상되는 데이터의 양과 관련이 있습니다. time 열 (읽기의 타임 스탬프)에서 작동하도록 위의 쿼리를 약간 수정하면 273,505 번 뚜렷한 목록을 얻는 데 1 분 40 초가 걸리고 대부분의 오버 헤드가 회로망. 따라서 얼마만큼의 데이터를 가져올 지에 대한 한계를 염두에 두십시오. 가져 오려는 데이터의 가능한 한 낮게 유지하려고합니다. 최종 쿼리로

:

select distinct line from car_cache 
where year='$postyear' and make='$postmake' 
order by line desc 

그냥 당신이 yearmakeline에 가능한 인덱스에 복합 인덱스가 있는지 확인, 그 중 하나에 문제가 없어야합니다. 마지막 주에

, 나는 수치 테이블에 대해 사용하고있는 엔진은 InnoDB에, 그리고 내 서버는 다음과 같습니다 도움이 Percona 사

희망에 의해 MySQL의 버전입니다 5.5.23-55-log Percona Server (GPL), Release 25.3을.

+1

최종 검색어의 경우 가장 좋은 색인은'(년, make, line)'또는'(make, year, line) '입니다. –

+0

완전한 철저한 답은 더 좋은 감사를 요구할 수 없습니다 :) – Wolfe