mysql查询需要很长时间才能执行

时间:2014-08-25 15:34:42

标签: mysql

这是我的查询需要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表中的多列columnType,deleteFlag,keyName,itemName上有索引IX_items_itemType_deleteFlag_keyName_itemName,并且在join和where子句中使用的其他表的列上也有索引。

那我怎样才能提高查询效果?

由于

2 个答案:

答案 0 :(得分:0)

你在那里做什么,就是你使用一个基本的表,然后你做一些'加入',只有在你做'你'的请求之后。要快速,请尝试将您的条件包含在“联接”中。在这种方式中,它选择“加入”请求中的不同行而不是之后。

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
    AND I.deleteflag = 0
LEFT OUTER JOIN icd
            ON icd.code = D.value
            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
            AND I.itemname LIKE 'A%'
            AND ( I.keyname = 'Assessments' )
ORDER  BY I.itemname ASC limit 0,6;  

答案 1 :(得分:0)

我会根据用于where子句和order by的多个键列在item表上有一个索引。我会在前面的位置设置最小结果的索引。例如,您专门寻找&#34;评估&#34;。如果您的表有100万条记录,其中600k是项目类型&#34;我&#34;,但只有5k是&#34;评估&#34;,那么预先最小的部分可能更适合您的查询处理。

我想要你的:

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'