【问题标题】:Optimising query with composite index, which says using where使用复合索引优化查询,其中使用 where
【发布时间】:2014-09-06 06:43:14
【问题描述】:

我有下表“残局”如下:

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, 'Using where' 2, 'UNION', 'endgames', 'ALL', 'IX_PieceCounts', '', '', '', 58795, '使用 where' , '联合结果', '', 'ALL', '', '', '', '', , ''

在具有 60,000 行的表的实时环境中,这可能需要长达 3 秒的时间。有什么办法可以优化查询吗?特别是我注意到在 UNION 之后的第二部分中没有使用 IX_PieceCounts 索引,我看到“使用位置”并且必须检查大量行。

提前致谢, 蒂姆

【问题讨论】:

  • 我能发现的最简单的事情是从两个 select 子句中去掉星号,只得到你需要的,你应该会看到一些改进。

标签: mysql performance optimization indexing range


【解决方案1】:

数据的重叠可能不足以保证第二次使用索引,我猜在你的大多数游戏中,两个玩家都会移动车超过 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多