簡體   English   中英

使用復合索引優化查詢,即使用何處

[英]Optimising query with composite index, which says using where

我的下表“殘局”如下:

DROP TABLE IF EXISTS `DB`.`endgames`; 
    CREATE TABLE `DB`.`endgames` ( 
    `ID` int(11) NOT NULL AUTO_INCREMENT, 
    `GamePosition` char(64) NOT NULL DEFAULT '0123421055555555CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBB6789A876', 
    `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; 

可以看出,在Count字段(我搜索的字段)上有一個復合索引。

我正在使用以下查詢:

說明

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 

聯盟

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,'PRIMARY','endgames','range','IX_PieceCounts','IX_PieceCounts','10','',8421,'在哪里使用'2,'UNION','endgames,'ALL',' IX_PieceCounts','','','',58795,'在哪里使用','UNION RESULT','','ALL','','','',``,''

在具有60,000行的表的實時環境中,這最多可能需要3秒鍾。 有什么方法可以優化查詢? 特別是,我注意到在UNION之后的第二部分中未使用IX_PieceCounts索引,並且看到“使用位置”和大量行必須檢查。

預先感謝,蒂姆

數據的重疊可能不足以保證第二次使用索引,我想在您的大多數游戲中,兩個玩家的選擇都超過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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM