当我使用OR增强查询时,我遇到了性能问题。
查询的简化版本如下。使用表单,用户可以向查询添加多个条件以缩小其结果。
SELECT DISTINCT DocL.DocumentLineId
FROM DocumentLine AS DocL
INNER JOIN DocumentField AS DocF00 ON DocF00.DocumentLineId = DocL.DocumentLineId
INNER JOIN DocumentField AS DocF01 ON DocF01.DocumentLineId = DocL.DocumentLineId
WHERE ( DocF00.DocumentType_FieldId = '383' AND DocF00.DocumentFieldValue = '113563' )
OR ( DocF01.DocumentType_FieldId = '383' AND DocF01.DocumentFieldValue = '46910043' )
;
如果我在没有最后一行的情况下运行查询,则需要不到一秒的时间。 使用查询中的OR行大约需要45秒。
DocumentLine表有大约75,000条记录。
DocumentField表有大约110万条记录。
除了各个ID的两个表上的主键之外,DocumentField还有DocumentLineId,DocumentType_FieldId和DocumentFieldValue上的索引。
所有Id字段为INT(11)。
DocumentType_FieldId大约有150个可能的值。
DocumentFieldValue是VARCHAR(250),几乎可以包含任何内容。
有关如何优化此查询的任何建议都将不胜感激。
ETA:效果数据作为链接上的图片。
CREATE TABLE `DocumentLine` (
`DocumentLineId` int(11) NOT NULL AUTO_INCREMENT,
`DocumentLineSequence` int(11) NOT NULL,
`DocumentLineCoordinates` varchar(45) DEFAULT NULL,
`DocumentLineElementId` int(11) DEFAULT NULL,
`DocumentType_LineId` int(11) NOT NULL,
`DocumentSectionId` int(11) NOT NULL,
PRIMARY KEY (`DocumentLineId`),
KEY `fk_DocumentLine_DocumentSection` (`DocumentSectionId`),
KEY `fk_DocumentLine_DocumentTypeLine` (`DocumentType_LineId`),
CONSTRAINT `fk_DocumentLine_DocumentSection` FOREIGN KEY (`DocumentSectionId`) REFERENCES `DocumentSection` (`DocumentSectionId`) ON DELETE NO ACTION ON UPDATE CASCADE,
CONSTRAINT `fk_DocumentLine_DocumentTypeLine` FOREIGN KEY (`DocumentType_LineId`) REFERENCES `DocumentTypeLine` (`DocumentTypeLineId`) ON DELETE NO ACTION ON UPDATE NO ACTION);
CREATE TABLE `DocumentField` (
`DocumentFieldId` int(11) NOT NULL AUTO_INCREMENT,
`DocumentFieldValue` varchar(255) DEFAULT NULL,
`DocumentFieldCoordinates` varchar(45) DEFAULT NULL,
`DocumentType_FieldId` int(11) NOT NULL,
`DocumentLineId` int(11) NOT NULL,
`ElementId` int(11) NOT NULL,
PRIMARY KEY (`DocumentFieldId`),
KEY `idx_DocumentType_FieldId` (`DocumentType_FieldId`),
KEY `idx_DocumentLineId` (`DocumentLineId`),
KEY `idx_DocumentFieldValue` (`DocumentFieldValue`),
KEY `idx_TypeId_Value` (`DocumentType_FieldId`,`DocumentFieldValue`));
PS:这是我第一次就Stack Overflow提出问题,如果我没有遵循协议,请提前道歉。
答案 0 :(得分:0)
我认为你不需要两个连接来获得你想要的东西。 试试这个:
SELECT DISTINCT dl.DocumentLineId
FROM DocumentField AS df
INNER JOIN DocumentLine AS dl ON dl.DocumentLineId = df.DocumentLineId
WHERE df.DocumentType_FieldId = 383
AND (
df.DocumentFieldValue = '113563'
OR df.DocumentFieldValue = '46910043'
)
;
如果您只想从 DocumentLine 表中获取 DocumentLineId ,那么您根本不需要加入:
SELECT DISTINCT df.DocumentLineId
FROM DocumentField AS df
WHERE df.DocumentType_FieldId = 383
AND (
df.DocumentFieldValue = '113563'
OR df.DocumentFieldValue = '46910043'
)
;
如果我们想要搜索不同的字段类型( DocumentType_FieldId )并使用 LIKE ,也没有问题:
SELECT DISTINCT df.DocumentLineId
FROM DocumentField AS df
WHERE ( df.DocumentType_FieldId = '383' AND df.DocumentFieldValue LIKE '%113563%' )
OR ( df.DocumentType_FieldId = '384' AND df.DocumentFieldValue LIKE '%46910043%' )
OR ( df.DocumentType_FieldId = '123' AND df.DocumentFieldValue LIKE '%SMITH%' )
OR ( df.DocumentType_FieldId = '234' AND df.DocumentFieldValue LIKE '%what%ever%' )
;
如果您需要更多字段,可以将其与 DocumentLine 表联系起来。你几乎可以立刻得到结果。