2014-07-21 5 views
0

빠를 수백만 레코드와이 개 테이블에 조인 만들기 두 테이블내가 가진

security_stat => 가진 4 백만 기록 내가 가진

security_trade => 가진 10 개 수백만 기록

이 쿼리는 성공적으로 실행되지만 어떻게 수행 할 수 있습니까? 10 초 이내에 적어도 100,000 개의 레코드를 쿼리 할 수 ​​있습니다 (가능합니까?). 현재 매우 느립니다.

SELECT `sec_stat_sec_name`, `sec_stat_date`, `sec_stat_market`, `sec_trade_close`, `sec_stat_date` 
FROM security_stat` LEFT JOIN `security_trade` 
ON `security_trade`.`sec_trade_sec_name` = `security_stat`.`sec_stat_sec_name` 
    and `security_trade`.`sec_trade_date` = `security_stat`.`sec_stat_date` 
limit 100,000 

은 내가 sec_stat_date이> = 2005-01-01하지만 많은 도움이되지 않습니다 WHERE 로 결과를 제한하는 시도

sec_stat_date sec_trade_sec_name, sec_stat_sec_name, sec_trade_date에 INDEX를 가지고있다. (내 기록은 1975 범위 - 2014)

편집

security_stat 스키마

CREATE TABLE `security_stat` (
    `sec_stat_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `sec_stat_date` date NOT NULL, 
    `sec_stat_sec_name` varchar(255) NOT NULL, 
    `sec_stat_sec_id` int(11) NOT NULL, 
    `sec_stat_market` varchar(255) NOT NULL, 
    `sec_stat_industry` int(11) NOT NULL, 
    `sec_stat_sector` int(11) NOT NULL, 
    `sec_stat_subsector` int(11) NOT NULL, 
    `sec_stat_sec_type` varchar(1) NOT NULL, 
    `sec_stat_status` varchar(2) NOT NULL, 
    `sec_stat_benefit` varchar(2) NOT NULL, 
    `sec_stat_listed_share` bigint(20) NOT NULL, 
    `sec_stat_earn_p_share` decimal(12,5) NOT NULL, 
    `sec_stat_value` decimal(9,2) NOT NULL, 
    `sec_stat_p_of_earn` int(11) NOT NULL, 
    `sec_stat_as_date` date NOT NULL, 
    `sec_stat_div_p_share` decimal(16,12) NOT NULL, 
    `sec_stat_p_of_div` int(11) NOT NULL, 
    `sec_stat_end_date_div` date NOT NULL, 
    `sec_stat_pe` decimal(8,2) NOT NULL, 
    `sec_stat_pbv` decimal(8,2) NOT NULL, 
    `sec_stat_div_yield` decimal(8,2) NOT NULL, 
    `sec_stat_par_value` decimal(16,5) NOT NULL, 
    `sec_stat_market_cap` decimal(20,2) NOT NULL, 
    `sec_stat_turn_ratio` decimal(8,2) NOT NULL, 
    `sec_stat_npg_flag` varchar(1) NOT NULL, 
    `sec_stat_acc_div` decimal(16,12) NOT NULL, 
    `sec_stat_acc_no_of_pay` int(11) NOT NULL, 
    `sec_stat_div_pay_ratio` decimal(6,2) NOT NULL, 
    `sec_stat_earn_date` date NOT NULL, 
    `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `sec_stat_ev` decimal(20,2) DEFAULT NULL, 
    `sec_stat_ev_revenue` decimal(20,2) DEFAULT NULL, 
    `sec_stat_ev_ebit` decimal(20,2) DEFAULT NULL, 
    `sec_stat_ev_ebitda` decimal(20,2) DEFAULT NULL, 
    `sec_stat_earning_yield` decimal(10,5) DEFAULT NULL, 
    `sec_stat_ps_ratio` decimal(10,5) DEFAULT NULL, 
    PRIMARY KEY (`sec_stat_id`), 
    UNIQUE KEY `sec_stat_date_name_id_cap` (`sec_stat_date`,`sec_stat_market`,`sec_stat_sec_id`,`sec_stat_sector`), 
    KEY `sec_stat_date` (`sec_stat_date`), 
    KEY `sec_stat_sec_name` (`sec_stat_sec_name`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3598612 ; 

security_trade 스키마

CREATE TABLE `security_trade` (
    `sec_trade_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `sec_trade_date` date NOT NULL, 
    `sec_trade_sec_name` varchar(20) NOT NULL, 
    `sec_trade_sec_id` int(11) NOT NULL, 
    `sec_trade_market` varchar(1) NOT NULL, 
    `sec_trade_trading_method` varchar(1) NOT NULL, 
    `sec_trade_trade_report` varchar(1) NOT NULL, 
    `sec_trade_prior_date` date NOT NULL, 
    `sec_trade_prior` decimal(8,2) NOT NULL, 
    `sec_trade_open` decimal(8,2) NOT NULL, 
    `sec_trade_high` decimal(8,2) NOT NULL, 
    `sec_trade_low` decimal(8,2) NOT NULL, 
    `sec_trade_close` decimal(8,2) NOT NULL, 
    `sec_trade_last_bid` decimal(8,2) NOT NULL, 
    `sec_trade_last_offer` decimal(8,2) NOT NULL, 
    `sec_trade_transaction` int(11) NOT NULL, 
    `sec_trade_volume` bigint(20) NOT NULL, 
    `sec_trade_value` decimal(20,2) NOT NULL, 
    `sec_trade_avg_price` decimal(8,2) NOT NULL, 
    `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    PRIMARY KEY (`sec_trade_id`), 
    UNIQUE KEY `sec_trade_close` (`sec_trade_date`,`sec_trade_sec_name`,`sec_trade_market`,`sec_trade_trade_report`,`sec_trade_trading_method`), 
    KEY `security_trade_sec_trade_sec_name_index` (`sec_trade_sec_name`), 
    KEY `security_trade_sec_trade_date_index` (`sec_trade_date`), 
    KEY `security_trade_sec_trade_prior_date_index` (`sec_trade_prior_date`), 
    KEY `security_trade_sec_trade_close_index` (`sec_trade_close`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=10019817 ; 

내 최종 쿼리는 실제로 더 많은 것

WHERE sec_stat_earning_yield IS NULL 
ORDER BY updated_at ASC 
,

그러나이 두 문장을 1,000 레코드 LIMIT가 포함 된 쿼리에 추가하면 쿼리가 느려집니다 (이 두 열에 인덱스가 없기 때문일 수 있습니다?) 사전에

감사

+0

자신을보기 위해'explain select ...'실행 –

+2

테이블에 어떤 색인이 있습니까? 이러한 인덱스는 조인 및 where 절에 해당합니까? 100k 레코드의 제한을 지정하지만 order by 절이 없습니다 * (임의의 100k 레코드, 가장 최근의 100k 레코드 등이 필요합니까?) * 스키마를 지정하지 않으므로 'sec_trade_sec_name, sec_trade_date'가 하나 또는 다른 테이블에서 고유한지 여부를 알려줍니다. – MatBailie

+0

코멘트 주셔서 감사합니다, 내 질문을 스키마로 업데이 트했습니다. 사실 한 번 더 WHERE 절을 가지고 있고 updated_at 명령을 사용하고 싶습니다.하지만 내 쿼리가 더 느려지 게됩니다. (** 해당 인덱스에 ** 인덱스 **가 없기 때문일 수 있습니다.) – cjmling

답변