SQL添加order by后性能非常慢(也有可能是查询条件)!求高手帮忙优化下。。。

hackerws2013 2013-01-06 05:12:56
SELECT TOP 50 * FROM vw_App_Appointment WHERE 1 = 1 AND user_department_id = 1000 ORDER BY appointment_id DESC
此句代码时候后,执行时间非常慢,大于需要40多S。

SELECT TOP 50 * FROM vw_App_Appointment WHERE 1 = 1 AND user_department_id = 1000
SELECT TOP 50 * FROM vw_App_Appointment ORDER BY appointment_id DESC
而当这两句分别执行时候,大约也就1S左右。

为什么性能会相差这么多呢?该怎么优化第一句SQL?
...全文
1920 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
hackerws2013 2013-01-07
  • 打赏
  • 举报
回复
哦,谢谢了,结贴。。。
Mr_Nice 2013-01-07
  • 打赏
  • 举报
回复
引用 11 楼 hackerws2013 的回复:
呃。。。 如9楼所说,为表Acc_User表添加了覆盖索引,就好了,但是不知道原理是为什么。。。
因为利用原索引找到USER_ID 的时候,还需要找到user_real_name,但索引中没有,就得全表扫描一下。 建个覆盖索引,就不用再扫描全表,速度就上来了。
hackerws2013 2013-01-07
  • 打赏
  • 举报
回复
呃。。。 如9楼所说,为表Acc_User表添加了覆盖索引,就好了,但是不知道原理是为什么。。。
Mr_Nice 2013-01-07
  • 打赏
  • 举报
回复
另外,lz图片下面应该还有vw_Acc_User 的相关执行计划。 实在图片费劲,lz把文本的发上来看看也行。 SET STATISTICS PROFILE ON select ... --lz的视图 执行一下,结果中会出现相应的执行计划。这个发上来也行。
Mr_Nice 2013-01-07
  • 打赏
  • 举报
回复
SELECT  dbo.App_Appointment.appointment_id ,
        dbo.App_Appointment.appointment_state ,
        CASE WHEN dbo.App_Appointment.appointment_state = 'N' THEN '未到'
             ELSE '已到'
        END AS appointment_state_text ,
        CASE WHEN dbo.App_Appointment.appointment_visit = '' THEN 'N'
             ELSE 'Y'
        END AS appointment_visit_state ,
        CASE WHEN dbo.App_Appointment.appointment_visit = '' THEN '未回访'
             ELSE '已回访'
        END AS appointment_visit_state_text ,
        CASE WHEN dbo.App_Appointment.appointment_visit_arrive IS NULL
             THEN 'N'
             ELSE dbo.App_Appointment.appointment_visit_arrive
        END AS appointment_visit_arrive ,
        dbo.App_Appointment.appointment_user_name ,
        dbo.App_Appointment.appointment_user_sex ,
        dbo.App_Appointment.appointment_user_age ,
        dbo.App_Appointment.appointment_user_phone ,
        dbo.App_Appointment.appointment_user_qq ,
        dbo.App_Appointment.appointment_specialist_number ,
        dbo.App_Appointment.appointment_is_consume ,
        CASE WHEN dbo.App_Appointment.appointment_is_consume = 'N' THEN '未消费'
             ELSE '已消费'
        END AS appointment_is_consume_text ,
        dbo.App_Appointment.appointment_keywords ,
        dbo.App_Appointment.appointment_advisory ,
        dbo.App_Appointment.appointment_note ,
        dbo.App_Appointment.appointment_ailment ,
        dbo.App_Appointment.appointment_remark ,
        dbo.App_Appointment.appointment_visit ,
        dbo.App_Appointment.appointment_time_arrive ,
        dbo.App_Appointment.appointment_time_create ,
        dbo.App_Appointment.appointment_source_id ,
        dbo.App_Appointment.appointment_area_id ,
        dbo.App_Appointment.user_id ,
        dbo.App_Source.source_name ,
        dbo.App_Area.area_name ,
        dbo.vw_Acc_User.user_real_name ,
        dbo.vw_Acc_User.user_department_id ,
        dbo.vw_Acc_User.department_name ,
        dbo.App_Appointment.appointment_abteilung_id ,
        dbo.Abt_Abteilung.abteilung_name ,
        dbo.vw_Acc_User.user_hospital_id ,
        dbo.vw_Acc_User.hospital_name ,
        dbo.App_Appointment.appointment_to_qq ,
        CASE WHEN dbo.App_Appointment.appointment_to_qq = 'N' THEN '未转'
             ELSE '已转'
        END AS appointment_to_qq_text ,
        dbo.App_Appointment.appointment_to_phone ,
        CASE WHEN dbo.App_Appointment.appointment_to_phone = 'N' THEN '未转'
             ELSE '已转'
        END AS appointment_to_phone_text ,
        dbo.App_Appointment.appointment_doctor_id ,
        dbo.Acc_User.user_real_name AS doctor_name ,
        dbo.App_Appointment.appointment_evaluation ,
        dbo.App_Appointment.appointment_clinic_number
FROM    dbo.App_Appointment  --该表字段提取很多,执行计划中 键查找的部分,也表明了这点,lz也可以考虑使用覆盖索引,用空间换时间
        LEFT OUTER JOIN dbo.Acc_User ON dbo.App_Appointment.appointment_doctor_id = dbo.Acc_User.USER_ID   --Acc_User 索引扫描,占了13% ,但上面输出只有一列user_real_name,lz可以建里一个覆盖索引 USER_ID和user_real_name
        LEFT OUTER JOIN dbo.Abt_Abteilung ON dbo.App_Appointment.appointment_abteilung_id = dbo.Abt_Abteilung.abteilung_id
        LEFT OUTER JOIN dbo.App_Source ON dbo.App_Appointment.appointment_source_id = dbo.App_Source.source_id
        LEFT OUTER JOIN dbo.App_Area ON dbo.App_Appointment.appointment_area_id = dbo.App_Area.area_id
        LEFT OUTER JOIN dbo.vw_Acc_User ON dbo.App_Appointment.user_id = dbo.vw_Acc_User.USER_ID  --如果是视图的话,看看能否做成索引视图,如果不是注意user_id列的索引状况。
        
hackerws2013 2013-01-07
  • 打赏
  • 举报
回复


视图:
SELECT dbo.App_Appointment.appointment_id, dbo.App_Appointment.appointment_state,
CASE WHEN dbo.App_Appointment.appointment_state = 'N' THEN '未到' ELSE '已到' END AS appointment_state_text,
CASE WHEN dbo.App_Appointment.appointment_visit = '' THEN 'N' ELSE 'Y' END AS appointment_visit_state,
CASE WHEN dbo.App_Appointment.appointment_visit = '' THEN '未回访' ELSE '已回访' END AS appointment_visit_state_text,
CASE WHEN dbo.App_Appointment.appointment_visit_arrive IS NULL THEN 'N' ELSE dbo.App_Appointment.appointment_visit_arrive END AS appointment_visit_arrive,
dbo.App_Appointment.appointment_user_name, dbo.App_Appointment.appointment_user_sex, dbo.App_Appointment.appointment_user_age,
dbo.App_Appointment.appointment_user_phone, dbo.App_Appointment.appointment_user_qq, dbo.App_Appointment.appointment_specialist_number,
dbo.App_Appointment.appointment_is_consume,
CASE WHEN dbo.App_Appointment.appointment_is_consume = 'N' THEN '未消费' ELSE '已消费' END AS appointment_is_consume_text,
dbo.App_Appointment.appointment_keywords, dbo.App_Appointment.appointment_advisory, dbo.App_Appointment.appointment_note,
dbo.App_Appointment.appointment_ailment, dbo.App_Appointment.appointment_remark, dbo.App_Appointment.appointment_visit,
dbo.App_Appointment.appointment_time_arrive, dbo.App_Appointment.appointment_time_create, dbo.App_Appointment.appointment_source_id,
dbo.App_Appointment.appointment_area_id, dbo.App_Appointment.user_id, dbo.App_Source.source_name, dbo.App_Area.area_name,
dbo.vw_Acc_User.user_real_name, dbo.vw_Acc_User.user_department_id, dbo.vw_Acc_User.department_name, dbo.App_Appointment.appointment_abteilung_id,
dbo.Abt_Abteilung.abteilung_name, dbo.vw_Acc_User.user_hospital_id, dbo.vw_Acc_User.hospital_name, dbo.App_Appointment.appointment_to_qq,
CASE WHEN dbo.App_Appointment.appointment_to_qq = 'N' THEN '未转' ELSE '已转' END AS appointment_to_qq_text, dbo.App_Appointment.appointment_to_phone,
CASE WHEN dbo.App_Appointment.appointment_to_phone = 'N' THEN '未转' ELSE '已转' END AS appointment_to_phone_text,
dbo.App_Appointment.appointment_doctor_id, dbo.Acc_User.user_real_name AS doctor_name, dbo.App_Appointment.appointment_evaluation,
dbo.App_Appointment.appointment_clinic_number
FROM dbo.App_Appointment LEFT OUTER JOIN
dbo.Acc_User ON dbo.App_Appointment.appointment_doctor_id = dbo.Acc_User.user_id LEFT OUTER JOIN
dbo.Abt_Abteilung ON dbo.App_Appointment.appointment_abteilung_id = dbo.Abt_Abteilung.abteilung_id LEFT OUTER JOIN
dbo.App_Source ON dbo.App_Appointment.appointment_source_id = dbo.App_Source.source_id LEFT OUTER JOIN
dbo.App_Area ON dbo.App_Appointment.appointment_area_id = dbo.App_Area.area_id LEFT OUTER JOIN
dbo.vw_Acc_User ON dbo.App_Appointment.user_id = dbo.vw_Acc_User.user_id
發糞塗牆 2013-01-06
  • 打赏
  • 举报
回复
贴的不全,把百分比最大的那部分贴上来。
hackerws2013 2013-01-06
  • 打赏
  • 举报
回复
hackerws2013 2013-01-06
  • 打赏
  • 举报
回复
SQL SERVER 2008里,怎么查看执行计划呢?
hackerws2013 2013-01-06
  • 打赏
  • 举报
回复
我创建索引的时候会提示创建失败,视图中不能带有OUTER。。
nzperfect 2013-01-06
  • 打赏
  • 举报
回复
看上去像是一个视图。。。 如果这两个列同在一个表,那么建一个索引会提高效率: 类似下面的:
create index ix_test on vw_App_Appointment (user_department_id, appointment_id)
KevinLiu 2013-01-06
  • 打赏
  • 举报
回复
第一条执行计划贴一下
hackerws2013 2013-01-06
  • 打赏
  • 举报
回复
自己顶一下,数据量大概是4W左右。。。
通过sql分析的学习,了解什么是sql,以及SQL会引起那些性能问题。清楚sql日志的设置,然后再通过sql分析工具的学习,清楚sql分析的步骤和流程。sql分析工具:mysqldumpslow工具、explain工具、profile工具、Optimizer Trace工具。 提供课程中所使用的sql语句。 课程内容:第一章:课程简介1、课程介绍2、课程大纲 第二章:sql简介1、sql简介2、sql会引起的问题 第三章:日志的设置1、sql的分析流程2、日志参数理解3、日志参数设置:第1种方式:my.ini文件设置4、日志参数设置:第2种方式:sql脚本设置5、日志参数设置-效果验证 第四章:如何发现sql1、如何发现sql:第1种方式:日志文件2、如何发现sql:第2种方式:mysql库的slow_log表 第五章:sql分析工具1、sql提取-mysqldumpslow工具-使用方法2、sql提取-mysqldumpslow工具-操作实战3、sql的执行计划分析-explain分析-执行计划结果说明4、sql的执行计划分析-explain分析-索引介绍+type类型举例5、sql的资源开销分析-profile分析-分析步骤6、sql的资源开销分析-profile分析-show profile执行阶段说明7、sql的资源开销分析-profile分析-完整列表说明+操作实战8、sql的跟踪分析-Optimizer Trace分析-分析步骤9、sql的跟踪分析-Optimizer Trace表的介绍10、索引失效场景举例 第六章:日志清理1、日志清理

22,207

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧