2011-11-18 2 views
1

필자는 검색해야하는 1 000 000 레코드가있는 phpmyadmin 데이터베이스가 있습니다. 매주 500 000 레코드가 추가되었습니다.sql 쿼리가 느림

location_id value date  time  name    lat  lng 
3   234 2011-11-18 19:50:00 Amerongen beneden 5.40453 51.97486 
4   594 2011-11-18 19:50:00 Amerongen boven  5.41194 51.97507 

내가이 쿼리와 함께이 작업을 수행 : 30 초 정도 걸립니다

SELECT location_id, value, date, time, locations.name, locations.lat, locations.lng FROM 
(
SELECT location_id, value, date, time from `measurements` 
LEFT JOIN units ON (units.id = measurements.unit_id) 
WHERE units.name='Waterhoogte' 
ORDER BY measurements.date DESC, measurements.time DESC 
) as last_record 
LEFT JOIN locations on (locations.id = location_id) 
GROUP BY location_id 

그래서,이게 내가해야 할 것입니다. 어떻게 개선 할 수 있습니까? 이것은 내 구조입니다 :

CREATE TABLE IF NOT EXISTS `locations` (
    `id` int(11) NOT NULL auto_increment, 
    `name` varchar(255) NOT NULL, 
    `code` varchar(255) NOT NULL, 
    `lat` varchar(10) NOT NULL, 
    `lng` varchar(10) NOT NULL, 
    `owner_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=244 ; 

-- -------------------------------------------------------- 

-- 
-- Table structure for table `measurements` 
-- 

CREATE TABLE IF NOT EXISTS `measurements` (
    `id` int(11) NOT NULL auto_increment, 
    `date` date NOT NULL, 
    `time` time NOT NULL, 
    `value` varchar(255) NOT NULL, 
    `location_id` int(11) NOT NULL, 
    `unit_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=676801 ; 

-- -------------------------------------------------------- 

-- 
-- Table structure for table `owner` 
-- 

CREATE TABLE IF NOT EXISTS `owner` (
    `id` int(11) NOT NULL auto_increment, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; 

-- -------------------------------------------------------- 

-- 
-- Table structure for table `units` 
-- 

CREATE TABLE IF NOT EXISTS `units` (
    `id` int(11) NOT NULL auto_increment, 
    `name` varchar(255) NOT NULL, 
    `description` text NOT NULL, 
    `unit_short` varchar(255) NOT NULL, 
    `owner_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=44 ; 

phpmyadmin에서 처리 할 수있는 제한은 무엇입니까?

+1

phpmyadmin 제한이 아니라는 점을 분명히 밝히고 싶습니다. mySql이 쿼리를 실행할 수있는 속도입니다. – Dallas

+2

참고 : phpmyadmin은 데이터베이스가 아닙니다. 이것은 MySQL 기반 데이터베이스 서버에 PHP 기반의 ** 인터페이스 **입니다. –

답변

4

units.name에 색인을 생성하면 특히 유용합니다. 철회하려는 데이터의 양을 실제로 재고해야합니다. 누군가가 실제로 많은 기록을 탐색하려고합니다. 쿼리 수를 변경하여 레코드 수를 제한하고 페이징 메커니즘과 관련된 UI 인터페이스를 생각해보십시오.

+0

나는 units.name = 'Waterhoogte'를 WHERE units.id = 4로 대체하여 2 초로 줄였습니다. 더 나은 방법으로이 쿼리를 다시 작성할 수있는 다른 방법이 있습니까? – Melvin

+0

이 필드에 색인이 있습니까? location.id에도 색인이 있어야 할 수 있습니다. 궁극적으로 쿼리를 "빨리"만들 수있는 방법은 거의 없습니다. 그것은 얼마나 많은 레코드를 클라이언트로 되돌려 놓을 지 문제가됩니다. 이를 제한하고 필요할 때 더 많은 레코드를 트리거하는 멋진 UI를 작성하십시오. 그 많은 기록을 되 찾는 것은 단지 아니오입니다. Google 검색을 수행하면 결과 40 페이지가 표시되며 대부분의 경우 두 번째 페이지까지만 첫 번째 2 페이지 만 관리합니다. – JonH

+0

오케이, 고마워! : 행 0 - 29 (총 30 개, 쿼리 소요 1.4580 초)를 표시 할 수 있습니다.이 – Melvin

2

units.name에 색인이나 고유 색인을 넣어야합니다.

1

다음 인덱스를 추가

unit.name 및 unit.id.에 지수 (피복 률)
measurements.date 및 measurements.time의 종합 색인입니다.
location.id의 색인

0

첫 번째 단계로 units.name에 대한 색인을 작성해야합니다. 그러나 인덱스와의 단점이 있음을 이해하십시오. 읽기 작업은 빠르지 만 쓰기 작업이 느려질 수 있습니다. 걱정이되거나 느린 쓰기의 영향을받는 경우 작은 수의 문자 (units.name)로 색인을 생성 해보십시오.

단위 ON INDEX first_twelve를 CREATE (이름 (12));

예를 들어, units.name의 처음 12 자에 인덱스를 선언하려면 다음을 선언 할 것

다시 말해서 인덱스를 던져서 부작용을 느끼지 않으면이 사실을 염두에 두어야합니다.

0
SELECT measurements.location_id, measurements.value, measurements.date, measurements.time, locations.name, locations.lat, locations.lng 
FROM measurements 
LEFT JOIN units ON units.id = measurements.unit_id 
LEFT JOIN locations ON locations.id = measurements.location_id 
WHERE units.id = 4 
GROUP BY measurements.location_id 
ORDER BY measurements.date DESC, measurements.time DESC 
+0

감사합니다, 그것은 더 빠르지 만 ASC에 의한 "측정"에서 기록을 보여줍니다, 나는 가장 최근 기록을 원합니다. 그룹에 의해 주문하기 전에 주문해야합니다.나는 이것이 어떻게 작동하는지 파악할 수 없다. 이 쿼리는 실제로 처음에있었습니다. – Melvin

+0

@Melvin은 where 절에서 하위 쿼리를 사용하는 것이 더 빠를 것입니다. 'date = 최대 날짜 선택'. 그럼 당신은 당신의 그룹화와 순서를 제거 할 수 있습니다. 또한 한 datetime 필드에서 날짜와 시간을 갖는 것이 더 빠를 것입니다. 그러나 그것은 또 다른 이야기입니다. – dqhendricks