2012-08-07 2 views
1

현재 data_article_key_terms 테이블에 약 900,000 개의 항목이있어 주요 용어를 각각의 기사와 연관시킵니다. 목표는 임의의 기간을 선택하고 해당 기간의 기사를 기반으로 상위 15 개 핵심 용어를 표시하는 것입니다.빈도 및 날짜 범위별로 키워드 순위 지정

제가 실행중인 문제는 제가 실행중인 쿼리가 거의 6 초가 걸리는 것입니다. 그러나 그보다 빠른 속도가 필요합니다. 나는이 시스템이 내가 실행중인 시스템을 기반으로하며 더 많은 성능을 가진 시스템을 사용할 수 있다는 것을 알고 있습니다. 그러나 그 경로를 가기 전에 최선을 다해 최적화 할려고합니다.

저는 데이터 무결성을 보존하기 위해 InnoDB를 MySQL 스토리지 엔진으로 사용하고 있습니다. MyISAM은 카운트 (*)가 빠르다고 이해하지만,이 엔진을 사용하는 것도 옵션이 아닙니다.

나는 고정 된 시간 범위를 기반으로 테이블에 주요 용어 수를 저장하는 것을 고려해 보았지만 저장 및 추적하기위한 많은 데이터가 필요하게되었습니다.

누구나이 경험을 최적화하는 방법에 대한 좋은 제안이 있습니까?

I가 다음과 같은 테이블 :

이 테이블에는 기사 정보 :

CREATE TABLE `data_article` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `connection_id` int(11) NOT NULL, 
    `folder_id` int(11) NOT NULL, 
    `user_id` int(11) NOT NULL, 
    `uid` varchar(100) NOT NULL, 
    `date` date NOT NULL, 
    `influencer_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `data_article_5930b15a` (`connection_id`), 
    KEY `data_article_4e5f642` (`folder_id`), 
    KEY `data_article_fbfc09f1` (`user_id`), 
    KEY `data_article_43ae76a1` (`influencer_id`), 
    KEY `data_article_date` (`date`), 
    CONSTRAINT `connection_id_refs_id_b2ae9152` FOREIGN KEY (`connection_id`) REFERENCES `account_connection` (`id`), 
    CONSTRAINT `folder_id_refs_id_e343586a` FOREIGN KEY (`folder_id`) REFERENCES `account_folder` (`id`), 
    CONSTRAINT `influencer_id_refs_id_45cd3615` FOREIGN KEY (`influencer_id`) REFERENCES `data_influencer` (`id`), 
    CONSTRAINT `user_id_refs_id_aca13cc9` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) 
) 

이 테이블에는 주요 용어 :

CREATE TABLE `data_keyterm` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `term` varchar(100) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `data_keyterm_term` (`term`) 
) 

이 테이블에는 기사와 주요 용어 사이의 관계 :

CREATE TABLE `data_article_key_terms` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `article_id` int(11) NOT NULL, 
    `keyterm_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `article_id` (`article_id`,`keyterm_id`), 
    KEY `data_article_key_terms_30525a19` (`article_id`), 
    KEY `data_article_key_terms_1d848ca4` (`keyterm_id`), 
    CONSTRAINT `article_id_refs_id_d87be8f5` FOREIGN KEY (`article_id`) REFERENCES `data_article` (`id`), 
    CONSTRAINT `keyterm_id_refs_id_50d233f8` FOREIGN KEY (`keyterm_id`) REFERENCES `data_keyterm` (`id`) 
) 
기사와 관련된

이 테이블에는 영향력이 주파수에 의해 SQL의 나는 시간 범위 그룹을 기반으로 키워드를 당겨 사용하고 문 및 주문 그들이다

CREATE TABLE `data_influencer` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(100) NOT NULL, 
    `title` varchar(100) NOT NULL, 
    `email` varchar(100) NOT NULL, 
    `active` tinyint(1) NOT NULL, 
    `user_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `data_influencer_fbfc09f1` (`user_id`), 
    KEY `data_influencer_name` (`name`), 
    CONSTRAINT `user_id_refs_id_b1bb5d4f` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`) 
) 

:

SELECT dk.id, dk.term as term, COUNT(dk.id) as count 
FROM data_keyterm dk 
INNER JOIN data_article_key_terms dakt ON dakt.keyterm_id = dk.id 
INNER JOIN data_article da ON da.id = dakt.article_id 
INNER JOIN data_influencer di ON di.id = da.influencer_id 
WHERE da.user_id = 1 
AND da.date between '2010-08-07' AND '2012-08-07' 
AND di.active = True 
GROUP BY dk.id 
ORDER BY count DESC 
LIMIT 15; 
+0

마지막 SQL 문이 유효한 GROUP BY 문으로 보이지 않습니다. 다시 한번 확인해 주시겠습니까? – Olaf

+0

예,이 문은 문제없이 실행됩니다. – bmorrise

+0

@Olaf : 유효한 SQL GROUP BY 절이 아니지만 [MySQL에서는 유효합니다] (http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html). –

답변

0

900,000 개의 레코드와 3 개의 내부 조인이있는 테이블로 내부 조인을 실행하려면 약간의 시간이 걸립니다. 나는 빠른 시간에 결과를 얻기 위해 태양과 같은 외부 검색 엔진을 시도해야한다고 생각한다.

+0

Solr이 이와 같은 검색을 처리 할 수 ​​있습니까? – bmorrise

+0

네, 처리합니다. 당신은이 같은 결과를 얻기 위해 인덱스를 적절하게 생성해야합니다. – Ashish

+0

Solr tip 주셔서 감사합니다. 나는 그것을 사용하는 것을 끝내었고 아름답게 작동했다. – bmorrise

0

나는이 경우 색인이 도움이되지 않을지 궁금해. 쿼리의 선택도는 무엇입니까? 즉, 얼마나 많은 기사/키 조합을 사용하고 있습니까?

성능을 최적화하려면 쿼리 계획에서 사용자 ID와 날짜로 항목을 선택한 다음 조인을 수행해야한다고 생각합니다. 그런 다음 추가 조인을 위해이 축소 된 하위 집합을 가져옵니다. 나는 그것이 대신 인덱스를 사용하고 있다고 생각합니다.

첫 번째 제안은 articles 테이블의 userid/date에있는 두 개의 인덱스를 단일 인덱스로 대체하는 것입니다. WHERE 절은이 단일 색인을 사용하여 조건을 만족시킬 수 있습니다. 이렇게하면 쿼리 계획이 단순 해지고 향상 될 수 있습니다.

테스트 할 또 다른 사항은 기사/키 테이블을 비정규 화하는 것입니다. 키와 아티클이 동시에 생성되었다고 가정하면이 테이블에 사용자 ID와 날짜를 추가하십시오. 그런 다음이 테이블의 제한 사항으로 쿼리를 수정하십시오. 그런 다음 사용자 ID와 날짜에 대한 복합 색인을 가질 수 있습니다. 그러나이 필드에 별도의 인덱스를 제안하지는 않습니다.

관련 문제