2014-09-06 46 views
0

我有以下表「殘局」如下:複合指數,其表示使用優化查詢,其中

DROP TABLE IF EXISTS `DB`.`endgames`; 
    CREATE TABLE `DB`.`endgames` ( 
    `ID` int(11) NOT NULL AUTO_INCREMENT, 
    `GamePosition` char(64) NOT NULL DEFAULT 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBB6789A876', 
    `GameIntroduction` text, 
    `Event` varchar(40) DEFAULT NULL, 
    `Site` varchar(40) DEFAULT NULL, 
    `GameDate` varchar(25) DEFAULT NULL, 
    `Round` varchar(10) DEFAULT NULL, 
    `WhitePlayer` varchar(80) NOT NULL, 
    `BlackPlayer` varchar(80) DEFAULT NULL, 
    `Result` tinyint(3) unsigned DEFAULT NULL, 
    `ECOCode` smallint(6) unsigned DEFAULT NULL, 
    `Annotator` varchar(100) DEFAULT NULL, 
    `EventCountry` varchar(40) DEFAULT NULL, 
    `GameText` text, 
    `WhiteMove` bit(1) DEFAULT b'1', 
    `MoveOffset` smallint(6) DEFAULT '0', 
    `TextComments` int(10) unsigned DEFAULT NULL, 
    `VariationCount` int(10) unsigned DEFAULT NULL, 
    `WhiteQueenCount` tinyint(3) unsigned NOT NULL, 
    `WhiteRookCount` tinyint(3) unsigned NOT NULL, 
    `WhiteBishopCount` tinyint(3) unsigned NOT NULL, 
    `WhiteKnightCount` tinyint(3) unsigned NOT NULL, 
    `WhitePawnCount` tinyint(3) unsigned NOT NULL, 
    `BlackQueenCount` tinyint(3) unsigned NOT NULL, 
    `BlackRookCount` tinyint(3) unsigned NOT NULL, 
    `BlackBishopCount` tinyint(3) unsigned NOT NULL, 
    `BlackKnightCount` tinyint(3) unsigned NOT NULL, 
    `BlackPawnCount` tinyint(3) unsigned NOT NULL, 
    PRIMARY KEY (`ID`), 
    KEY `IX_PieceCounts` (`WhiteQueenCount`,`WhiteRookCount`,`WhiteBishopCount`,`WhiteKnightCount`,`WhitePawnCount`,`BlackQueenCount`,`BlackRook 
    Count`,`BlackBishopCount`,`BlackKnightCount`,`BlackPawnCount`) 
    ) ENGINE=MyISAM AUTO_INCREMENT=58796 DEFAULT CHARSET=latin1; 

如可以看到的,存在對計數字段的複合指數(I查詢的字段上)。

我使用下面的查詢:

EXPLAIN

SELECT * FROM endgames WHERE WhiteQueenCount >=0 AND WhiteRookCount >=3 AND WhiteBishopCount >=0 AND WhiteKnightCount >=0 AND WhitePawnCount >=0 AND BlackQueenCount >=0 AND BlackRookCount >=0 AND BlackBishopCount >=0 AND BlackKnightCount >=0 AND BlackPawnCount >=0 

UNION

SELECT * FROM endgames WHERE WhiteQueenCount >=0 AND WhiteRookCount >=0 AND WhiteBishopCount >=0 AND WhiteKnightCount >=0 AND WhitePawnCount >=0 AND BlackQueenCount >=0 AND BlackRookCount >=3 AND BlackBishopCount >=0 AND BlackKnightCount >=0 AND BlackPawnCount >=0 

的那個輸出解釋如下:

1, '主要', 'endgames','range','IX_PieceCounts','IX_PieceCounts','10','',8421,'Where where' 2,'UNION','endgames','ALL','IX_PieceCounts','','','',58795,'Where where' ,'UNION RESULT','','ALL','' ,'','','',,''

在帶有60,000行的表格上,這可能需要3秒鐘的實時環境。有什麼辦法可以優化查詢嗎?特別是我注意到,在UNION之後的第二部分中沒有使用IX_PieceCounts索引,並且我看到「使用where」和大量行必須被檢查。

由於提前, 添

+0

我可以發現的最簡單的事情就是從這兩個select子句中取出明星,只取得你需要的東西,你應該看到一些改進。 – 2014-09-06 11:54:46

回答

0

的數據中重合可能不是大到足以保證使用第二時間而言,我大部分的遊戲猜測指數,雙方球員將移動車不止3次,所以你在第一次聯合查詢中得到了大部分(但不是全部)的結果。

如果你的查詢沒有被參數化,或者沒有其他東西取決於它,你可以嘗試把這個聯合出來。 同時選擇你想查詢的字段,而不是明星,這將需要一段時間。它必須是兩個相同的選擇。

SELECT 
    games.ID, 
    IF(blackRookCount3.ID IS NULL,0,1) AS blackRookIsGreaterThan3, 
    IF(whiteRookCount3.ID IS NULL,0,1) AS whiteRookIsGreaterThan3 
FROM endgames 

INNER JOIN 
    endgames games 
ON endgames.ID = games.ID  
AND WhiteQueenCount >=0 
AND WhiteBishopCount >=0 
AND WhiteKnightCount >=0 
AND WhitePawnCount >=0 
AND BlackQueenCount >=0 
AND BlackBishopCount >=0 
AND BlackKnightCount >=0 
AND BlackPawnCount >=0 

LEFT JOIN 
    endgames blackRookCount3 
ON endgames.ID = blackRookCount3.ID  
AND blackRookCount3.BlackRookCount >=3 

LEFT JOIN 
    endgames whiteRookCount3 
ON endgames.ID = whiteRookCount3.ID  
AND whiteRookCount3.WhiteRookCount >=3 

INNER JOIN 
    endgames whiteAndBlackRooks 
ON games.ID = whiteAndBlackRooks.ID  
AND whiteRookCount3.ID IS NOT NULL 
AND blackRookCount3.ID IS NOT NULL