2014-12-23 18 views
1

我有結構的兩個表,可被描述如下: MySQL的使用索引條件

CREATE TABLE `sub_schedule` (
    `ScheduleID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `ServiceID` bigint(20) unsigned NOT NULL, 
    `RunTime` time NOT NULL, 
    `Status` char(1) NOT NULL DEFAULT 'A', 
    `Telco` text, 
    PRIMARY KEY (`ScheduleID`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 
CREATE TABLE `mt` (
    `MtID` int(15) unsigned NOT NULL AUTO_INCREMENT, 
    `ServiceID` bigint(20) unsigned NOT NULL, 
    `Moperator` varchar(10) NOT NULL, 
    `Cmd` varchar(20) NOT NULL, 
    `CreateDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 
    PRIMARY KEY (`MtID`), 
    KEY `CreateDate` (`CreateDate`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

山表是大一個和sub_schedule表保持少於500個記錄。

當我嘗試運行此查詢:

EXPLAIN 
SELECT m.serviceid 
     , m.createdate 
     , m.moperator 
    FROM mt m 
    JOIN sub_schedule ss 
    ON m.serviceid = ss.serviceid 
    AND ss.status = "A" 
    AND ss.telco LIKE CONCAT('%', m.moperator, '%') 
    WHERE m.createdate >= addtime((subdate(curdate(), 1)),ss.runtime) 
    AND m.createdate <= addtime((subdate(curdate(), 0)),ss.runtime) 
    AND m.cmd LIKE "SUBS%"; 

它產生這樣的輸出:

id, select_type, table, type, possible_keys, key , key_len, ref , rows  , Extra 
1, SIMPLE  , ss , ALL , NULL   , NULL , NULL , NULL ,  470 , Using where 
1, SIMPLE  , m , ALL , CreateDate , NULL , NULL , NULL , 57610462 , Range checked for each record (index map: 0x10) 

它似乎並不在查詢這導致很長的使用索引createdate查詢執行時間。已經嘗試使用FORCE INDEX以及該查詢的不同方法,並嘗試將createdate移動到ON條件部分並使用FORCE INDEX FOR JOIN。 所以我的問題是:有什麼辦法讓mysql實際使用索引爲createdate的字段?

+0

你可以發佈哪些是你創建的索引。 –

回答

0

mt.serviceid沒有索引,因此必須掃描mt的所有行才能滿足條件m.serviceid = ss.serviceid。此表上的其他條件可以並將在全表掃描期間進行檢查。

mt(serviceid, createdate)mt(createdate, serviceid)上添加索引(不確定哪一個會產生最佳效果)。

注意:如果您決定使用並索引mt(createdate, serviceid),那麼索引mt(createdate)becomes superfluous

+0

感謝您的回覆。我將'serviceid'索引添加到mt表中,但它仍然掃描每條記錄 – Tezd

+0

查詢返回多少行?沒有WHERE條款有多少?當查詢返回大多數行時,優化器可能會決定不使用索引。另外,請確保你在'serviceid' **和''createdate'(不僅僅是'serviceid')上創建了一個**複合索引**。 – RandomSeed

+0

Nah,即使索引僅在'serviceid'上,該索引也可以用於JOIN條件。我想你的查詢只是返回表中的大部分行。 – RandomSeed