加where查询需要14秒,不加的话也有2秒,实际数据只有160行,怎么优化?
SELECT
e.equip_id,
e.equip_name,
f.fact_name,
ed.dept_name,
eb.buy_date,
eb.price,
dp.months/12 AS depr_year,
CASE 
WHEN datediff(month,dp.start_date,GETDATE()) >= dp.months THEN eb.price
WHEN datediff(month,dp.start_date,GETDATE()) < dp.months THEN eb.price / dp.months * datediff(month,dp.start_date,GETDATE())
END AS depr_amount,--折旧金额= 设备原值/ 折旧期限* 使用时间
CASE 
WHEN datediff(month,dp.start_date,GETDATE()) >= dp.months THEN '0'
WHEN datediff(month,dp.start_date,GETDATE()) < dp.months THEN eb.price - eb.price / dp.months * datediff(month,dp.start_date,GETDATE())
END AS equip_worth, --净值 = 设备购置金额 - 已设备折旧金额
SUM(dtl.EQUIP_USE_NUM) AS USE_NUM, --使用次数
SUM(dtl.PERCENT_FEE) AS PERCENT_FEE --费用 FROM
AMS_PERFORM_EQUIP pe 
LEFT JOIN AMS_EQUIP e ON pe.EQUIP_ID = e.equip_id
LEFT JOIN AMS_EQUIP_BUY eb ON e.buy_id = eb.buy_id
LEFT JOIN AMS_FACTORY f ON f.fact_id = eb.product_id
LEFT JOIN AMS_EQUIP_DEPT ed ON e.equip_id = ed.equip_id
LEFT JOIN temp_equip_perform_dtl temp ON temp.EQUIP_ID = e.equip_id  
LEFT JOIN AMS_EQUIP_PERFORM_DTL dtl ON e.equip_id = dtl.EQUIP_ID AND pe.status = '正常' 
LEFT JOIN AMS_DEPRECIATION_PLAN dp ON e.equip_id = dp.equip_id
WHERE temp.perform_year = '2012' AND temp.perform_month = '12' --加where后 执行需要14秒 GROUP BY 
e.equip_id,
e.equip_name,
f.fact_name,
ed.dept_name,
eb.buy_date,
eb.price,
dp.months,
dp.start_date,
dtl.PROJECT_FEE,
dtl.PROJECT_UNIT优化sql

解决方案 »

  1.   

    看到这一堆left join和group by, 我跪了..熟悉业务的话, 先想下怎么把逻辑优化了再说。
      

  2.   

    perform_year /perform_month这两个没索引吧?
      

  3.   


    这个表(temp_equip_perform_dtl)是新建的,没有建立任何索引
      

  4.   


    没有 倒是有一条这个警告:警告: 聚合或其他 SET 操作消除了空值。
      

  5.   


    我是刚来这个公司实习,上来就是做这块的新功能,对业务了解不多,写这个sql语句都是凭当时在学校里学的那点在做..
      

  6.   

    如果没有的话,当where用到这些列,就会导致扫描。性能更低。试一下加上去看看
      

  7.   


    我不知道我的理解对不对啊.
    因为我用 AMS_PERFORM_EQUIP 作为主表 (仅173条数据)
    这几个连接的表中最多的也就3000条数据.这样的一个查询即便是没有索引,也不会这么的慢吧?我试着将"temp.perform_year = '2012' AND temp.perform_month = '12'"写在"LEFT JOIN temp_equip_perform_dtl temp ON temp.EQUIP_ID = e.equip_id  " 之后,这样速度是快了,但是也会将 dtl里的空值查询出来,却不是想要的结果.
      

  8.   

    我不知道我的理解对不对啊.
    因为我用 AMS_PERFORM_EQUIP 作为主表 (仅173条数据)
    这几个连接的表中最多的也就3000条数据.这样的一个查询即便是没有索引,也不会这么的慢吧?这个跟有没有用到索引没有必然的关系
    我试着将"temp.perform_year = '2012' AND temp.perform_month = '12'"写在"LEFT JOIN temp_equip_perform_dtl temp ON temp.EQUIP_ID = e.equip_id  " 之后,这样速度是快了,但是也会将 dtl里的空值查询出来,却不是想要的结果. 
    不要为了快而改,你的查询首先要满足你的业务需求,否则秒杀也没用
    先把你的业务逻辑弄清楚,然后看看能否改写你的查询,再处理索引的问题
      

  9.   

    如果你有10个表关联,每个表100条,那么数据实际会加载100^10这么多数据
    当然在缓存中这些操作是很快的,然后再进行数据匹配,再用函数处理,慢了很正常~一般left join后面除了关联条件,不要加其他条件,条件一律写在where中,因为表达的意思不一致
    08的话用预估计划应该能看到索引缺失,应该是一行绿色的小字