Mysql 左连接查询太慢,以至于超时
下面的查询运行时间太长,最终只是超时。我看了解释计划,它似乎没有使用我的一个表的索引,所以我假设这与它有关,尽管我不确定为什么会发生这种情况。问题是:Mysql 左连接查询太慢,以至于超时,mysql,Mysql,下面的查询运行时间太长,最终只是超时。我看了解释计划,它似乎没有使用我的一个表的索引,所以我假设这与它有关,尽管我不确定为什么会发生这种情况。问题是: SELECT documentID , coID , suiteID , leaseID , assetID , vendorID , feed_documents.did , document_links.doid FROM feed_documents LEFT
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
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 )
下面是解释的结果:
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\u documents表在所有的select/join列上都有索引,document\u 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
我看到您希望查询中的
doid
为NULL
和feed\u documents.did=document\u links.doid
据我所知,这意味着将feed\u documents.did=null的所有行join
连接到document\u links.doid
的所有行。
这是一种多对多关系,因此您的查询速度很慢也就不足为奇了,尤其是当您在feed_文档中有许多行的did=null
和文档链接中有许多行的doid=null
时
如果第一个表中有n
匹配行,第二个表中有m
匹配行,则结果集将包含n*m
行,这些行可能会很大,具体取决于您的数据
不管怎样,为什么一次需要75000行
PS
如果查询超时,您的查询可能会很慢,可能有一个或两个表被另一个查询锁定。解决了这个问题。只是需要一种不同的查询方法:
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
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 )
请显示show create table feed\u文档的输出代码>和显示创建表文档链接代码>。explain
看起来很合理——在第二个表上进行索引查找。在选择中,文档链接.doid
字段是不必要的,但这可能不是问题。也许其他进程在表上有锁,会影响查询性能。那么主进程呢,唯一和索引?请注意,没有ORDER BY的限制在表的详细信息中是没有意义的-我不认为还有其他锁在运行,因为这个应用程序还没有向许多用户推出,而且这个特定区域还没有太多活动。如果我限制在0,2000,它将在30-40秒内完成。