这是我的查询,执行时间为 3 秒:
SELECT I.itemname,
I.overdue,
D.value,
I.itemid,
icd.ecwstatus AS status,
C.inactiveflag AS inactive,
icd.validfrom,
icd.validto
FROM items I
JOIN itemdetail D
ON I.itemtype = 'I'
AND I.itemid = D.itemid
AND D.propid = 13
LEFT OUTER JOIN icd
ON icd.code = D.value
LEFT OUTER JOIN edi_icdcodes C
ON I.itemid = C.itemid
WHERE I.deleteflag = 0
AND ( icd.validfrom <= '2012-12-06'
OR icd.validfrom IS NULL )
AND ( icd.validto >= '2012-12-06'
OR icd.validto IS NULL )
AND I.itemname LIKE 'A%'
AND ( I.keyname = 'Assessments' )
ORDER BY I.itemname ASC limit 0,6;
我在 items 表中的多个列 itemType 、 deleteFlag 、keyName 、itemName 上有索引 IX_items_itemType_deleteFlag_keyName_itemName ,并且在 join 和 where 子句中使用的其他表的列上也有索引。
那么如何提高查询性能?
谢谢
最佳答案
我会根据用于 where 子句和 order by 的多个键列在您的 items 表上建立一个索引。我会将具有最小结果集的索引放在前面的位置。例如,您专门寻找“评估”。如果您的表有 100 万条记录,其中 600k 属于项目类型“I”,但只有 5k 属于“评估”,那么前面的最小部分可能更适合您的查询 TO 处理。
我想要你的:
items table indexed on ( keyname, itemtype, deleteflag, itemname )
ItemDetail table, indexed ON ( itemid, propid )
icd table indexed ON ( code, validfrom, validto, ecwstatus )
edi_icdcodes table index ON (itemid)
SELECT
I.itemname,
I.overdue,
D.value,
I.itemid,
icd.ecwstatus AS status,
C.inactiveflag AS inactive,
icd.validfrom,
icd.validto
FROM
items I
JOIN itemdetail D
ON I.itemid = D.itemid
AND D.propid = 13
LEFT OUTER JOIN icd
ON D.value = icd.code
AND ( icd.validfrom <= '2012-12-06'
OR icd.validfrom IS NULL )
AND ( icd.validto >= '2012-12-06'
OR icd.validto IS NULL )
LEFT OUTER JOIN edi_icdcodes C
ON I.itemid = C.itemid
WHERE
I.itemtype = 'I'
AND I.deleteflag = 0
AND I.keyname = 'Assessments'
AND I.itemname LIKE 'A%'
ORDER BY
I.itemname ASC
LIMIT
0,6;
注意...如果 ICD 表在创建记录时始终具有从/到日期的值,则您不需要测试 NULL,但要理解为什么通过左连接和放入在 where 子句中。因此,该部分可能会简化为
LEFT OUTER JOIN icd
ON D.value = icd.code
AND icd.validfrom <= '2012-12-06'
AND icd.validto >= '2012-12-06'
关于mysql查询需要很长时间才能执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25489437/