2011-06-24 34 views
1

當current_vacature_response包含88k條記錄並且daily_vacature_response包含10k條記錄時,以下查詢大約需要30秒才能執行。使用EXPLAIN我得出結論,current_vacature_response表中沒有使用索引。我已經添加了一些基本的索引,但似乎沒有人使用它們。我需要設置什麼類型的索引來加速此查詢?我需要添加哪些索引以加速此MYSQL JOIN/GROUP BY/HAVING查詢?

查詢:

SELECT c.`stats_date` as `stats_date` 
    FROM `current_vacature_response` c 
    LEFT JOIN `daily_vacature_response` d ON (c.`stats_date` = d.`stats_date`) 
    GROUP BY c.`stats_date`, d.`stats_date` 
    HAVING max(d.`last_stats_datetime`) IS NULL 
     OR MAX(d.`last_stats_datetime`) < MAX(c.`created_datetime`); 

current_vacature_response表定義:

CREATE TABLE `current_vacature_response` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `created_datetime` datetime NOT NULL, 
    `site_id` tinyint(1) unsigned NOT NULL, 
    `stats_date` date NOT NULL, 
    `type` enum('typ1', 'type2') NOT NULL, 
    `vacature` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `current_vacature_created_datetime` (`created_datetime`), 
    KEY `current_vacature_response_vacature` (`vacature`), 
    KEY `current_vacature_response_type` (`type`), 
    KEY `current_vacature_stats_date` (`stats_date`) 
) ENGINE=MyISAM AUTO_INCREMENT=88210 DEFAULT CHARSET=utf8; 

daily_vacature_response表定義:

CREATE TABLE `daily_vacature_response` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `contact` int(10) unsigned NOT NULL DEFAULT '0', 
    `site_id` tinyint(1) unsigned NOT NULL, 
    `spotlight_result` int(10) unsigned NOT NULL DEFAULT '0', 
    `stats_date` date NOT NULL, 
    `last_stats_datetime` datetime NOT NULL, 
    `vacature` int(10) unsigned NOT NULL, 
    `created_datetime` datetime NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `daily_vacature_response_key` (`site_id`,`vacature`,`stats_date`), 
    KEY `daily_vacature_response_last_stats_datetime` (`last_stats_datetime`), 
    KEY `daily_vacature_response_stats_date` (`stats_date`) 
) ENGINE=MyISAM AUTO_INCREMENT=9802 DEFAULT CHARSET=utf8; 

解釋輸出:

*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: c 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 88209 
     Extra: Using temporary; Using filesort 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: d 
     type: ref 
possible_keys: daily_vacature_response_stats_date 
      key: daily_vacature_response_stats_date 
     key_len: 3 
      ref: reporting_development.c.stats_date 
     rows: 99 
     Extra: 
+2

你過濾僅HAVING子句,這是所有其他操作之後進行,所以它太遲到它使用索引。您可以做的最好的方式是重寫查詢,以便在早期階段(在where子句或聯接條件中)執行篩選。否則MySQL將不得不掃描整個current_vacature_response表。所以唯一的解決方案是重寫查詢,但爲了正確執行,請解釋stats_date,created_datetime,last_stats_datetime。你還可以提供一些示例輸入和預期輸出嗎? –

+0

TNX,我已經重寫它更快的查詢(4毫秒):選擇c.'stats_date' \t FROM'current_cv_response'Ç \t GROUP BY c.'stats_date' \t HAVING MAX(c.'created_datetime')NOT IN \t(SELECT MAX(d.'last_stats_datetime') \t \t FROM'daily_cv_response' d \t \t WHERE d.'stats_date' = c.'stats_date' \t \t GROUP BY d.'stats_date'); –

回答

1

嘗試使用daily_vacature_response(stats_date, last_stats_datetime)索引。

我很懷疑它會產生巨大的差異,但這是最有可能的候選人。

此外,嘗試重寫查詢一點點(在MySQL可能無法正常工作,但值得一試):

GROUP BY c.`stats_date`, c.`created_datetime`, d.`stats_date` 
HAVING max(d.`last_stats_datetime`) IS NULL 
    OR max(d.`last_stats_datetime`) < c.`created_datetime`;