我有下表“残局”如下:
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', '残局', '范围', 'IX_PieceCounts', 'IX_PieceCounts', '10', '', 8421, '使用位置' 2、'UNION'、'残局'、'ALL'、'IX_PieceCounts'、''、''、''、58795、'使用位置' , '并集结果', '', '全部', '', '', '', '', , ''
在实时环境中,对于具有 60,000 行的表,这可能最多需要 3 秒。有什么办法可以优化查询吗?特别是,我注意到在 UNION 之后的第二部分中没有使用 IX_PieceCounts 索引,并且我看到“using where”以及必须检查大量行。
提前致谢, 蒂姆
最佳答案
数据的重叠可能不足以保证第二次使用索引,我猜在你的大多数游戏中,两个玩家都会移动车超过 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
关于mysql - 使用复合索引优化查询,即使用where,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25697608/