12
返回列表 发新帖
楼主: lfree

[笔记] 问一个sql的优化

[复制链接]
论坛徽章:
33
ITPUB元老
日期:2005-09-16 10:42:482012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主3段
日期:2012-05-15 15:24:11马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14
11#
发表于 2008-6-19 17:14 | 只看该作者
原帖由 lfree 于 2008-6-6 10:06 发表
SELECT DISTINCT "OPERATION_BILL_ITEMS"."PATIENT_ID",
                "OPERATION_BILL_ITEMS"."OPER_ID", "PAT_MASTER_INDEX"."NAME",
                "PAT_MASTER_INDEX"."SEX", "PAT_MASTER_INDEX"."CHARGE_TYPE"
           FROM "PAT_MASTER_INDEX",
                "OPERATION_BILL_ITEMS",
                "SURGERY"."OPERATION_MASTER"
          WHERE ("SURGERY"."OPERATION_MASTER"."PATIENT_ID" =
                                           "OPERATION_BILL_ITEMS"."PATIENT_ID"
                )
            AND ("SURGERY"."OPERATION_MASTER"."VISIT_ID" =
                                             "OPERATION_BILL_ITEMS"."VISIT_ID"
                )
            AND ("SURGERY"."OPERATION_MASTER"."OPER_ID" =
                                              "OPERATION_BILL_ITEMS"."OPER_ID"
                )
            AND ("OPERATION_BILL_ITEMS"."PATIENT_ID" =
                                               "PAT_MASTER_INDEX"."PATIENT_ID"
                )
            AND (    (TO_CHAR ("OPERATION_MASTER"."START_DATE_TIME",
                               'YYYY-MM-DD'
                              ) = :operating_date
                     )
                 AND ("OPERATION_BILL_ITEMS"."PERFORMED_BY" = :performed_by)
                )

再贴一个,现在看军惠的sql写的真烂!!!!


这个SQL看不太明白程序员的意图,是不是想查一下在某天手术室有哪些操作员收了哪些病人的费用?为什么偏要指定执行科室?难道是其他科室要查看手术室替自己记了些什么费用么?如果是这样的话,为什么不显示明细,而只显示病人及其身份?

如果不需要限定执行科室,可以优化为如下语句:

SELECT b.PATIENT_ID,
                c.OPER_ID, b.NAME,
                b.SEX, b.CHARGE_TYPE
           FROM PAT_MASTER_INDEX b,
                SURGERY.OPERATION_MASTER c
          WHERE c.PATIENT_ID = b.PATIENT_ID
            AND ((TO_CHAR (c.START_DATE_TIME,'YYYY-MM-DD') = :operating_date);

使用道具 举报

回复
论坛徽章:
194
红宝石
日期:2014-05-09 08:24:37萤石
日期:2014-01-03 10:25:39奥运会纪念徽章:羽毛球
日期:2008-07-01 10:46:06奥运会纪念徽章:马术
日期:2008-07-07 17:43:24奥运会纪念徽章:射箭
日期:2008-07-25 18:07:39奥运会纪念徽章:皮划艇激流回旋
日期:2008-07-30 10:02:57奥运会纪念徽章:花样游泳
日期:2008-09-26 13:02:43奥运会纪念徽章:排球
日期:2008-12-03 11:23:272010新春纪念徽章
日期:2010-01-04 08:33:082010年世界杯参赛球队:澳大利亚
日期:2010-02-26 11:08:44
12#
 楼主| 发表于 2008-6-19 17:20 | 只看该作者
写错许多,改正一下。
SELECT a.retail_price, a.purchase_price
  FROM drug_export_detail a,
       drug_export_master b,
       (SELECT MAX (export_date) max_export_date
          FROM drug_export_detail m, drug_export_master x
         WHERE m.document_no = x.document_no
           AND x.STORAGE = :xx1
           AND m.drug_code = :xx2
           AND m.package_spec = :xx3
           AND m.firm_id = :xx4) c
WHERE a.document_no = b.document_no
   AND b.STORAGE = :xx1
   AND a.drug_code = :xx2
   AND a.package_spec = :xx3
   AND a.firm_id = :xx4
   AND b.export_date = c.max_export_date
   AND ROWNUM = 1

使用道具 举报

回复
论坛徽章:
194
红宝石
日期:2014-05-09 08:24:37萤石
日期:2014-01-03 10:25:39奥运会纪念徽章:羽毛球
日期:2008-07-01 10:46:06奥运会纪念徽章:马术
日期:2008-07-07 17:43:24奥运会纪念徽章:射箭
日期:2008-07-25 18:07:39奥运会纪念徽章:皮划艇激流回旋
日期:2008-07-30 10:02:57奥运会纪念徽章:花样游泳
日期:2008-09-26 13:02:43奥运会纪念徽章:排球
日期:2008-12-03 11:23:272010新春纪念徽章
日期:2010-01-04 08:33:082010年世界杯参赛球队:澳大利亚
日期:2010-02-26 11:08:44
13#
 楼主| 发表于 2008-6-19 17:21 | 只看该作者
这样确实快一些,主要是可以利用export_date索引。

使用道具 举报

回复
论坛徽章:
194
红宝石
日期:2014-05-09 08:24:37萤石
日期:2014-01-03 10:25:39奥运会纪念徽章:羽毛球
日期:2008-07-01 10:46:06奥运会纪念徽章:马术
日期:2008-07-07 17:43:24奥运会纪念徽章:射箭
日期:2008-07-25 18:07:39奥运会纪念徽章:皮划艇激流回旋
日期:2008-07-30 10:02:57奥运会纪念徽章:花样游泳
日期:2008-09-26 13:02:43奥运会纪念徽章:排球
日期:2008-12-03 11:23:272010新春纪念徽章
日期:2010-01-04 08:33:082010年世界杯参赛球队:澳大利亚
日期:2010-02-26 11:08:44
14#
 楼主| 发表于 2008-6-19 17:24 | 只看该作者
原帖由 fals 于 2008-6-19 17:14 发表


这个SQL看不太明白程序员的意图,是不是想查一下在某天手术室有哪些操作员收了哪些病人的费用?为什么偏要指定执行科室?难道是其他科室要查看手术室替自己记了些什么费用么?如果是这样的话,为什么不显示明细,而只显示病人及其身份?

如果不需要限定执行科室,可以优化为如下语句:

SELECT b.PATIENT_ID,
                c.OPER_ID, b.NAME,
                b.SEX, b.CHARGE_TYPE
           FROM PAT_MASTER_INDEX b,
                SURGERY.OPERATION_MASTER c
          WHERE c.PATIENT_ID = b.PATIENT_ID
            AND ((TO_CHAR (c.START_DATE_TIME,'YYYY-MM-DD') = :operating_date);


哈哈,我也不知道为什么?

使用道具 举报

回复
论坛徽章:
33
ITPUB元老
日期:2005-09-16 10:42:482012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主3段
日期:2012-05-15 15:24:11马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14
15#
发表于 2008-6-19 17:24 | 只看该作者
原帖由 lfree 于 2008-6-19 17:21 发表
这样确实快一些,主要是可以利用export_date索引。


改得挺对,我粗心了,没有仔细去看这些表的结构。

一方面可以使用export_date索引,另一方面去掉了不必要的group by ,这个可能引起硬盘排序

使用道具 举报

回复
论坛徽章:
33
ITPUB元老
日期:2005-09-16 10:42:482012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主3段
日期:2012-05-15 15:24:11马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14
16#
发表于 2008-6-19 17:27 | 只看该作者
原帖由 lfree 于 2008-6-19 17:24 发表


哈哈,我也不知道为什么?


这个SQL是从哪个窗口里跟踪出来的?抓个图出来看看吧,或者可以修改业务。

那个distinct挺讨厌的,多数情况下都会引起硬盘排序,如果能够去掉的话,会省很多

使用道具 举报

回复
论坛徽章:
194
红宝石
日期:2014-05-09 08:24:37萤石
日期:2014-01-03 10:25:39奥运会纪念徽章:羽毛球
日期:2008-07-01 10:46:06奥运会纪念徽章:马术
日期:2008-07-07 17:43:24奥运会纪念徽章:射箭
日期:2008-07-25 18:07:39奥运会纪念徽章:皮划艇激流回旋
日期:2008-07-30 10:02:57奥运会纪念徽章:花样游泳
日期:2008-09-26 13:02:43奥运会纪念徽章:排球
日期:2008-12-03 11:23:272010新春纪念徽章
日期:2010-01-04 08:33:082010年世界杯参赛球队:澳大利亚
日期:2010-02-26 11:08:44
17#
 楼主| 发表于 2008-6-20 09:04 | 只看该作者
fals 还是蛮厉害,一下就发现这个distinct。
就是这个distinct,程序员的素质太差了。

实际上不在于去掉,不知道程序员为什么这样写。

使用道具 举报

回复
论坛徽章:
33
ITPUB元老
日期:2005-09-16 10:42:482012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主3段
日期:2012-05-15 15:24:11马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14
18#
发表于 2008-6-20 17:39 | 只看该作者
是从性能视图里跟出来的么?如果是这样的话,很有必要把产生这个SQL的前台程序抓出来,多花点时间抓一下吧,估计可以去掉这个业务需求。

一条坏的SQL,可以搞死整个数据库。既然已经发现了,就不要放过去。

或者程序员自己都没明白为什么要写这个SQL呢,下面的人也就稀里糊涂地用。

使用道具 举报

回复
论坛徽章:
168
马上加薪
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:10:582012新春纪念徽章
日期:2012-01-04 11:49:54蜘蛛蛋
日期:2011-12-05 16:08:56ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41设计板块每日发贴之星
日期:2011-07-22 01:01:02ITPUB官方微博粉丝徽章
日期:2011-06-30 12:30:16管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:33
19#
发表于 2008-6-26 20:51 | 只看该作者
呵呵,没有任何背景知识,看这么长的sql还是有点吃力的。
补充一下,纯技术来看,可以试试用分析函数row_number代替rownum=1

使用道具 举报

回复
论坛徽章:
105
萤石
日期:2014-04-06 09:24:42天枰座
日期:2015-07-22 11:25:542014年世界杯参赛球队: 阿尔及利亚
日期:2014-07-10 09:12:26马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11
20#
发表于 2008-6-27 18:40 | 只看该作者
没有用过军惠,用Sqlserver的飘过

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表