2016-06-01 3 views
1

스크립트의 실행 시간에 약간의 문제가 있습니다. 쿼리에 많은 시간이 소요됩니다. 이 쿼리는 다음과 같습니다.쿼리 실행 시간 문제

select avg(price) from voiture where duration<30 AND make="Audi" AND model="A4" 

+---+---+---+---+---+---+---+---+---+---+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
+---+---+---+---+---+---+---+---+---+---+ 
| 1 | SIMPLE | voiture | ALL | NULL | NULL | NULL | NULL | 1376949 | Using where | 
+---+---+---+---+---+---+---+---+---+---+ 

select price from voiture where duration<30 AND make="Audi" AND model="A4" 
+---+---+---+---+---+---+---+---+---+---+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
+---+---+---+---+---+---+---+---+---+---+ 
| 1 | SIMPLE | voiture | ALL | NULL | NULL | NULL | NULL | 1376949 | Using where | 
+---+---+---+---+---+---+---+---+---+---+ 

이 쿼리는 phpMyAdmin 인터페이스에서 실행될 때 약 2 초가 걸립니다. 문제가 무엇인지 확인하려고 시도하고 평균 기능을 제거하면 쿼리가 0.0080 초 정도 지속됩니다.
나는 php 스크립트에서 평균을 계산하는 데 얼마나 걸릴지 자신에게 물어 보았지만, orouth와 avg를 함께 사용하는 쿼리에는 약 2 초가 걸렸다.
그래서 내 테이블의 모든 값을 가지고 스크립트의 처리를하기로 결정, 그래서이 쿼리를 사용하십시오 phpMyAdmin을 인터페이스에

select * from voiture where duration<30 AND make="Audi" AND model="A4" 

+---+---+---+---+---+---+---+---+---+---+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
+---+---+---+---+---+---+---+---+---+---+ 
| 1 | SIMPLE | voiture | ALL | NULL | NULL | NULL | NULL | 1376949 | Using where | 
+---+---+---+---+---+---+---+---+---+---+ 

를, 그것은 0.0112 초 정도 걸립니다. 하지만 내 PHP 스크립트에서 25 초 걸립니다! carid 및 서비스 id에 대한 인덱스가있어

CREATE TABLE `voiture` (
    `carid` bigint(9) NOT NULL, 
    `serviceid` bigint(9) NOT NULL, 
    `service` varchar(256) NOT NULL, 
    `model` varchar(256) DEFAULT NULL, 
    `gearingType` varchar(256) DEFAULT NULL, 
    `displacement` int(5) DEFAULT NULL, 
    `cylinders` int(2) DEFAULT NULL, 
    `fuel` varchar(32) DEFAULT NULL, 
    `mileage` int(7) DEFAULT NULL, 
    `existFlag` tinyint(1) DEFAULT NULL, 
    `lastUpdate` date DEFAULT NULL, 
    `version` varchar(256) DEFAULT NULL, 
    `bodyType` varchar(256) DEFAULT NULL, 
    `firstRegistration` date DEFAULT NULL, 
    `powerHp` int(4) DEFAULT NULL, 
    `powerKw` int(4) DEFAULT NULL, 
    `vat` varchar(256) DEFAULT NULL, 
    `price` decimal(12,2) DEFAULT NULL, 
    `duration` int(3) DEFAULT NULL, 
    `pageUrl` varchar(256) DEFAULT NULL, 
    `carImg` varchar(256) DEFAULT NULL, 
    `color` varchar(256) DEFAULT NULL, 
    `doors` int(1) DEFAULT NULL, 
    `seats` int(1) DEFAULT NULL, 
    `prevOwner` int(1) DEFAULT NULL, 
    `co2` varchar(256) DEFAULT NULL, 
    `consumption` varchar(256) DEFAULT NULL, 
    `gears` int(1) DEFAULT NULL, 
    `equipment` varchar(1024) NOT NULL, 
    `make` varchar(256) NOT NULL, 
    `country` varchar(3) NOT NULL 
) 


을 실행하는 내 쿼리가 너무 오래 걸리는 않습니다 여기
$timestart2=microtime(true); 
$querysec='select * from voiture where duration<30 AND make="Audi" AND model="A4"'; 
$requestsec=mysql_query($querysec) or die(mysql_error()); 
$timeend2=microtime(true); 
$time2=$timeend2-$timestart2; 
$page_load_time2 = number_format($time2, 9); 

는 테이블 구조인가? 개선 할 수있는 방법이 있습니까?
실행 시간이 phpMyAdmin 및 PHP 스크립트와 다른 이유는 무엇입니까?

+1

자세한 정보를 제공해야합니다. 테이블 구조는 무엇입니까? 색인을 생성하는 대상은 무엇입니까? 질의에 대해'EXPLAIN'을 실행 해 볼 수 있습니다. 출력물을 이해하지 못할 경우 질문에 추가하면 문제를 진단하는 데 도움이됩니다. –

+0

''* from voiture where duration <30 AND make = "Audi"AND model = "A4"'로 얼마나 많은 행이 반환됩니까? – beingalex

+0

[mysql_' 데이터베이스 확장 프로그램] (http://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php)을 사용하지 마십시오. 은 더 이상 사용되지 않습니다 (영원히 사라짐). PHP7에서) 특별히 PHP를 배우는 경우,'PDO' 데이터베이스 확장을 배우는 데 에너지를 소비하십시오. [여기에서 시작하십시오] (http://php.net/manual/en/book.pdo.php) 정말 쉽습니다. – RiggsFolly

답변

1

에 대한 인덱스를 추가 할 수 있습니다 등으로 더 빨리 GROUP을 사용하여 만들 수 있습니다, 그것은 0.0112 초 정도 걸립니다. 하지만 내 PHP 스크립트에서 25 초 걸립니다!

phpMyAdmin 인터페이스는 각 쿼리에 LIMIT을 추가합니다. 기본값은 LIMIT 30입니다.

집계 쿼리의 시간을 줄이려면 사용하는 각 조건 (또는 하나의 복합 인덱스 일 수도 있음)에 대한 인덱스를 만들어야합니다.

따라서 model, makeduration 필드의 색인을 만들어보십시오.


또한 테이블이 너무 비정규 화되어 있습니다. 테이블을 만들어서 정상화 할 수 있습니다.
예 : Vendors(id, name), Models(id, name)make/model 대신 voiturevendor_id/model_id 필드로 수정됩니다.그것은 텍스트 일치하는 빛 룩업 테이블을 스캔 및 인덱스 ID를 가진 무거운 테이블과 작동

select avg(t.price) from voiture t 
INNER JOIN Models m ON m.id = t.model_id 
INNER JOIN Vendors v ON v.id = t.vendor_id 
where t.duration<30 AND v.name="Audi" AND m.name="A4" 

: 같은

그런 다음 초기 쿼리가 보일 것이다.

+0

좋은 대답은, 내가 하나의 합성 색인에 3 개의 인덱스를 추가, 실행 시간은 25 초에서 1.5 초 갔다! 나는 이미 "make"와 "model"테이블을 가지고 있지만 행의 id는 make/model의 이름입니다. 그래서 make = "Audi"를 사용합니다. – Nevi

+0

또한 필자는 make와 모델 (사실 거의 모든 테이블 필드)보다 훨씬 더 많은 매개 변수를 사용합니다. 모든 필드를 복합 인덱스에 넣는 것이 좋은가요? – Nevi

+0

에 따라 다릅니다. 그것은 너무 뚱뚱한 색인 및 내부 검색 원시 테이블 전체 스캔에 대한 이익이 없습니다. 텍스트 기본 키 (당신은'varchar (256)'을 사용합니다) 역시 나쁜 생각입니다. –

0

가능한 많은 해결책이 있습니다. is create index을 DB 수준에서 수행하면 실행 시간이 향상 될 수 있습니다.

이 체크 서버보다 두 번째로 서버 리소스를 차지하고 서버를 느리게하는 프로세스가있을 수 있습니다.

0

당신은

select AVG(price) from voiture where duration<30 AND make="Audi" AND model="A4" GROUP BY make 

는 또한 당신은 phpMyAdmin을 인터페이스에 메이크업 열

ALTER TABLE `voiture` ADD INDEX `make` (`make`) 
+0

PHP 스크립트에서 가격을 선택하고 평균을 선택하십시오. (가격)은 같은 시간이 걸립니다. – Nevi

+0

I 대답을 바꾸었다. 이것이 작동하는지 확인하십시오. @ 네비 –