LEFT JOIN查询速度很慢,超时

时间:2015-01-08 22:59:31

标签: mysql

以下查询运行时间太长,最终只会超时。我查看了EXPLAIN计划,似乎它没有使用我的某个表格的索引,所以我认为这与它有关,虽然我不确定为什么会发生这种情况。这是查询:

SELECT documentID
     , coID
     , suiteID
     , leaseID
     , assetID
     , vendorID
     , feed_documents.did
     , document_links.doid
  FROM feed_documents
  LEFT 
  JOIN document_links 
    ON feed_documents.did = document_links.doid
 WHERE doid IS NULL
 LIMIT 0, 75000

以下是EXPLAIN的结果:

id  select_type table           type  possible_keys key   key_len ref                               rows    Extra
1   SIMPLE      feed_documents  ALL   NULL          NULL  NULL    119363                            NULL    NULL
1   SIMPLE      document_links  ref   doid          doid  4       rladmin_rlhpsi.feed_documents.did 12      Using where; Not exists; Using index

feed_documents表在所有select / join列上都有索引,document_links在所有列上都有索引。有人能看到我在这里做错了吗?

更新:表定义,按要求。

CREATE TABLE `feed_documents` (
 `documentID` int(11) NOT NULL DEFAULT '0',
 `documentTitle` varchar(250) COLLATE utf8_unicode_ci DEFAULT NULL,
 `documentFileName` varchar(500) COLLATE utf8_unicode_ci DEFAULT NULL,
 `documentDate` datetime DEFAULT NULL,
 `documentArchived` int(11) DEFAULT NULL,
 `documentTypeID` int(11) DEFAULT NULL,
 `coID` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
 `suiteID` int(11) DEFAULT NULL,
 `leaseID` int(11) DEFAULT NULL,
 `assetID` int(11) DEFAULT NULL,
 `vendorID` int(11) DEFAULT NULL,
 `did` int(11) DEFAULT NULL,
 PRIMARY KEY (`documentID`),
 KEY `coID` (`coID`),
 KEY `suiteID` (`suiteID`),
 KEY `leaseID` (`leaseID`),
 KEY `assetID` (`assetID`),
 KEY `vendorID` (`vendorID`),
 KEY `did` (`did`),
 KEY `documentTypeID` (`documentTypeID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci


CREATE TABLE `document_links` (
 `dlid` int(11) NOT NULL AUTO_INCREMENT,
 `daid` int(11) NOT NULL COMMENT 'Dataset ID',
 `linkid` int(11) NOT NULL COMMENT 'ID value of linked item',
 `doid` int(11) NOT NULL COMMENT 'Document ID',
 PRIMARY KEY (`dlid`),
 KEY `daid` (`daid`),
 KEY `linkid` (`linkid`),
 KEY `doid` (`doid`)
) ENGINE=MyISAM AUTO_INCREMENT=148767 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

2 个答案:

答案 0 :(得分:0)

我认为您希望doidNULLfeed_documents.did = document_links.doid中查询。

据我了解,这意味着join feed_documents.did = null所有document_links.doid行所有行did = null。 这是多对多的关系,您的查询很慢也就不足为奇了,特别是如果您在feed_documents中有很多行doid = null而且在document_links中有很多行n

如果第一个表中有m个匹配的行,而第二个表中有n*m个匹配的行,那么结果集将包含{{1}}行,这些行可能很大,具体取决于您的数据。

无论哪种方式,为什么一次需要75000行?

PS 单独留下您的查询可能会很慢如果超时可能其中一个或两个表被另一个查询锁定。

答案 1 :(得分:0)

想出来。只需要对查询采用不同的方法:

SELECT documentID, coID, suiteID, leaseID, assetID, vendorID, feed_documents.did
FROM feed_documents
WHERE feed_documents.did NOT IN (
    SELECT DISTINCT feed_documents.did
    FROM feed_documents
    JOIN document_links ON feed_documents.did = document_links.doid )