【发布时间】:2014-05-29 21:20:23
【问题描述】:
我有一个这样的查询:
SELECT DISTINCT devices1_.id AS id27_, devices1_.createdTime AS createdT2_27_, devices1_.deletedOn AS deletedOn27_,
devices1_.deviceAlias AS deviceAl4_27_, devices1_.deviceName AS deviceName27_, devices1_.deviceTypeId AS deviceT21_27_,
devices1_.equipmentVendor AS equipmen6_27_, devices1_.exceptionDetail AS exceptio7_27_, devices1_.hardwareVersion AS hardware8_27_,
devices1_.ipAddress AS ipAddress27_, devices1_.isDeleted AS isDeleted27_, devices1_.loopBack AS loopBack27_,
devices1_.modifiedTime AS modifie12_27_, devices1_.osVersion AS osVersion27_, devices1_.productModel AS product14_27_,
devices1_.productName AS product15_27_, devices1_.routerType AS routerType27_, devices1_.rundate AS rundate27_,
devices1_.serialNumber AS serialN18_27_, devices1_.serviceName AS service19_27_, devices1_.siteId AS siteId27_,
devices1_.siteIdA AS siteIdA27_, devices1_.status AS status27_, devices1_.creator AS creator27_, devices1_.lastModifier AS lastMod25_27_
FROM goldenvariation goldenconf0_
INNER JOIN devices devices1_ ON goldenconf0_.deviceId=devices1_.id
CROSS JOIN devices devices2_
WHERE goldenconf0_.deviceId=devices2_.id
AND (goldenconf0_.classType = 'policy-options')
AND DATE(goldenconf0_.rundate)=DATE('2014-04-14 00:00:00')
AND devices2_.isDeleted=0
AND EXISTS (SELECT DISTINCT(deviceId) FROM goldenvariation goldenconf3_
WHERE (goldenconf3_.goldenVariationType = 'MISMATCH')
AND (goldenconf3_.classType = 'policy-options')
AND DATE(goldenconf3_.rundate)=DATE('2014-04-14 00:00:00'))
AND EXISTS (SELECT DISTINCT (deviceId) FROM goldenvariation goldenconf4_
WHERE (goldenconf4_.goldenVariationType = 'MISSING')
AND (goldenconf4_.classType = 'policy-options')
AND DATE(goldenconf4_.rundate)=DATE('2014-04-14 00:00:00'));
它花费了太多时间,我如何重写查询并使其快速?
goldervariation的表结构是:
CREATE TABLE `goldenvariation` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`classType` VARCHAR(255) DEFAULT NULL,
`createdTime` DATETIME DEFAULT NULL,
`goldenValue` LONGTEXT,
`goldenXpath` VARCHAR(255) DEFAULT NULL,
`isMatched` TINYINT(1) DEFAULT NULL,
`modifiedTime` DATETIME DEFAULT NULL,
`pathValue` LONGTEXT,
`rundate` DATETIME DEFAULT NULL,
`value` LONGTEXT,
`xpath` VARCHAR(255) DEFAULT NULL,
`deviceId` BIGINT(20) DEFAULT NULL,
`goldenXpathId` BIGINT(20) DEFAULT NULL,
`creator` INT(10) UNSIGNED DEFAULT NULL,
`lastModifier` INT(10) UNSIGNED DEFAULT NULL,
`goldenVariationType` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK6804472AD99F2D15` (`deviceId`),
KEY `FK6804472A98002838` (`goldenXpathId`),
KEY `FK6804472A27C863B` (`creator`),
KEY `FK6804472A3617A57C` (`lastModifier`),
KEY `rundateindex` (`rundate`),
KEY `varitionidindex` (`id`),
KEY `classTypeindex` (`classType`),
CONSTRAINT `FK6804472A27C863B` FOREIGN KEY (`creator`) REFERENCES `users` (`userid`),
CONSTRAINT `FK6804472A3617A57C` FOREIGN KEY (`lastModifier`) REFERENCES `users` (`userid`),
CONSTRAINT `FK6804472A98002838` FOREIGN KEY (`goldenXpathId`) REFERENCES `goldenconfigurationxpath` (`id`),
CONSTRAINT `FK6804472AD99F2D15` FOREIGN KEY (`deviceId`) REFERENCES `devices` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1868865 DEFAULT CHARSET=latin1;
查询的解释计划是:
"1" "PRIMARY" "goldenconf0_" "ref" "FK6804472AD99F2D15,classTypeindex" "classTypeindex" "258" "const" "179223" "Using where; Using temporary"
"1" "PRIMARY" "devices2_" "eq_ref" "PRIMARY,deviceindex" "PRIMARY" "8" "cmdb.goldenconf0_.deviceId" "1" "Using where"
"1" "PRIMARY" "devices1_" "eq_ref" "PRIMARY,deviceindex" "PRIMARY" "8" "cmdb.goldenconf0_.deviceId" "1" ""
"3" "DEPENDENT SUBQUERY" "goldenconf4_" "index_subquery" "FK6804472AD99F2D15,classTypeindex" "FK6804472AD99F2D15" "9" "func" "19795" "Using where"
"2" "DEPENDENT SUBQUERY" "goldenconf3_" "index_subquery" "FK6804472AD99F2D15,classTypeindex" "FK6804472AD99F2D15" "9" "func" "19795" "Using where"
【问题讨论】:
-
如何将表加入查询而不是使用
EXISTS。它应该工作得更快。你也可以从ON中的子查询中指出你的where子句@ -
你能用一个简单的例子详细说明吗?这将是很大的帮助。
-
当子查询与外部查询不相关时,为什么要使用
exists?这是允许的,但看起来很奇怪。 -
@GordonLinoff 我现在正在尝试加入。这会是一个不错的选择吗?
标签: mysql sql performance join query-optimization