2012-01-19 2 views
4

우리는 책을 분석하는 시스템을 구현하고 있습니다. 이 시스템은 PHP로 작성되었으며 각 책에 대해 단어를 반복하고 각각을 분석하여 다양한 정규 표현식 및 기타 테스트에서 특정 플래그 (데이터베이스 필드로 변환 됨)를 설정합니다. 이것은 matches 테이블 결과WHERE 절을 사용하여 MySQL (MyISAM) COUNTs 가속화

, 아래의 예와 유사한 생략 된 대부분의 필드

 
+------------------------+--------------+------+-----+---------+----------------+ 
| Field     | Type   | Null | Key | Default | Extra   | 
+------------------------+--------------+------+-----+---------+----------------+ 
| id      | bigint(20) | NO | PRI | NULL | auto_increment | 
| regex     | varchar(250) | YES |  | NULL |    | 
| description   | varchar(250) | NO |  | NULL |    | 
| phonic_description  | varchar(255) | NO |  | NULL |    | 
| is_high_frequency  | tinyint(1) | NO |  | NULL |    | 
| is_readable   | tinyint(1) | NO |  | NULL |    | 
| book_id    | bigint(20) | YES |  | NULL |    | 
| matched_regex   | varchar(255) | YES |  | NULL |    | 
| [...]     |    |  |  |   |    | 
+------------------------+--------------+------+-----+---------+----------------+ 

tinyint, 0 또는 1. 경기 테이블 (25 개) 필드는 현재이다.

성냥표에 ~ 2,000,000 개의 행이 있으며 약 500 권의 책을 분석하여 출력합니다. 그것은 각 쿼리가 필요로 주요 지수 보고서를 가져올 수 분 이상 소요 현재, 그러나

SELECT COUNT(*) 
FROM matches 
WHERE is_readable = 1 
AND other_flag = 0 
AND another_flag = 1 

:

현재이 같은 matches 테이블을 쿼리 사이트의 "보고서"영역이있다 약 0.7 초. 쿼리 수준에서 캐싱 중이지만 초기 페이지로드에 너무 오래 걸립니다.

이처럼 데이터 세트를 관리하는 방법에 대해서는 경험이 많지 않으므로 누구나이 데이터를 저장하거나 쿼리하는 더 나은 방법을 알려줄 수 있습니까? 이 COUNT의 성능을 향상시키기 위해 MySQL과 함께 사용할 수있는 최적화가 있습니까? 아니면 다른 데이터베이스 또는 데이터 구조를 사용하는 것이 더 좋습니까?

현재 MyISAM 테이블과 VPS와 함께 MySQL을 사용하고 있으므로 새로운 데이터베이스 시스템으로 전환하는 것은 문제가되지 않습니다.

+3

무엇입니까 'SELECT [쿼리의 나머지 부분을] EXPLAIN'의 출력? – jcmeloni

+0

@jcmeloni http://dpaste.com/690316/ –

+0

Super; @Marek 및 다른 사람들이 설명한 솔루션에 대한 정확한 확인을 제공합니다. – jcmeloni

답변

4

둘 이상의 필드에서 선택하는 것처럼이 테이블에 다중 색인을 추가하십시오. 색인 아래에는 많은 도움이됩니다. 이러한 유형의 인덱스는 boolean/int 열에 매우 유용합니다. varchar 값 인덱스의 자세한 내용은 여기를 읽어 : http://dev.mysql.com/doc/refman/5.0/en/create-index.html

ALTER TABLE `matches` ADD INDEX (`is_readable`, `other_flag`, `another_flag`) 

한가지 더는 DB에 의해 사용되는 인덱스 확인 {전체 SQL 문을} EXPLAIN 사용하여 쿼리를 확인하는 것입니다. 그래서 예를 들어 당신이 쿼리를 실행해야합니다에

EXPLAIN ALTER TABLE `matches` ADD INDEX (`is_readable`, `other_flag`, `another_flag`) 

더 많은 정보를 설명합니다 http://dev.mysql.com/doc/refman/5.0/en/explain.html

+2

@AlanEdwardes, 더 많은 것을 최적화합니다. 가장 작은 결과 집합이 먼저 나열되어야합니다. 예 : IS_READABLE 플래그 = 1이면 50,000 개의 항목이 반환되고 OTHER_FLAG = 0이면 8,000 개의 레코드 만 반환됩니다. OTHER_FLAG를 인덱스의 첫 번째 위치에 놓습니다. 마찬가지로 "ANOTHER_FLAG"열을 고려하십시오. – DRapp

+0

감사합니다. 색인에서의 순서가 중요하다는 것을 전혀 알지 못했습니다. 색인 생성이 이동하는 방법 인 것 같습니다. –

+0

@AlanEdwardes, 당신은 ALTER 문과 함께'EXPLAIN'을 사용할 수 없습니다 [https://dev.mysql.com/doc/refman/5.7/en/using-explain.html](https://dev.mysql.com) /doc/refman/5.7/en/using-explain.html). 첫 번째 부분을보십시오 : 'EXPLAIN에 허용 된 설명문은 SELECT, DELETE, INSERT, REPLACE 및 UPDATE입니다. – onirix

5

인덱스를 사용해야하며 가장 자주 수행하는 열에서 색인을 생성해야합니다. WHERE.

ALTER TABLE `matches` ADD INDEX (`is_readable`) 

등 당신이 끝난 쿼리 및 유용을 통해 동일한 유형을하는 경우 또한, 여러 열을 기반으로 인덱스를 만들 수 있습니다

. phpMyAdmin은 테이블의 구조 페이지 하단에 인덱스 옵션을 가지고 있습니다.

+1

예. '(is_readable, other_flag'another_flag)에 대한 복합 (즉 멀티 컬럼) 인덱스는 많은 쿼리의 시간을 향상시켜야합니다. 문제는 잠재적으로 많은 양의 색인이 필요합니다. – Mchl

+0

감사합니다.문제는 필요한 많은 쿼리의 수 (너무 많은 인덱스)이지만 너무 빨리 삽입해야하는 데이터에 대한 액세스입니다. 불합리한 수의 색인이 있습니까? 위의 단일 테이블에서 25가 쓰기 속도에 많은 영향을 미쳤습니까? –

+1

속도는 주로 테이블의 데이터 양에 따라 다릅니다. 인덱스를 다시 작성해야하므로 INSERT/UPDATE가 더 느려집니다 (테이블의 데이터 양에 따라 다름). 나는 많은 색인을 만드는 조언을하지 않을 것이다. 좋은 방법은 동일한 열에 대해 서로 다른 순서로 적은 수의 다중 인덱스를 생성하고 EXPLAIN을 사용하여 DB가 어떤 인덱스를 사용하는지 확인하는 것입니다. 이것을 알고 나면 인덱스를 사용하지 않고 하나만 남겨 두십시오. 나중에 변경할 수 있으므로 테이블의 데이터 수가 증가하고 다른 인덱스가 더 최적 일 수 있습니다 때 반복 할 할 수 있습니다. 그것은 테이블의 특정 사용 및 데이터에 따라 달라집니다. –

관련 문제