这样简单的语句还如何优化...

ASE 12.5.3

如下简单的语句
select FY,count(FY) from K_MS..B_MS where LARQ between @KSSJ and @JSSJ group by FY

背景:
法院行业
K_MS..B_MS(民事),民事案件最多,该表内300W数据,为全市所有法院的案件
FY(法院代码)字段 北京市共30家左右法院
LARQ(案件的立案日期)
@KSSJ,@JSSJ为查询的开始时间和结束时间

也就是 这个查询是要将
一段时间内 所有案件按所属法院分组
也就是统计每个法院在期间内有多少案件

假设结果集中(统计时间段内)
共有30W条记录,30家法院每家1W

LARQ为该表的非聚簇索引
当查询用了LARQ做索引字段时 可以看到I/O有几十万
即便都是逻辑I/O了 都需要10秒以上的耗时
觉得这些IO应该很正常吧
毕竟索引页(LARQ)就要读那么多 然后有要去读数据页(FY)

那么现在要如何优化啊
这么长耗时一定是不可以的
数据库已经经过了基础参数优化

作者: 75708332   发布时间: 2010-08-17

应该贴一下查询计划的。
如果可以,考虑建立索引(LARQ ,FY)


北京清华紫光法院系统的占有率那么高,300万的数据就不行了? 也没个dba。
bs、

[ 本帖最后由 andkylee 于 2010-8-18 09:32 编辑 ]

作者: andkylee   发布时间: 2010-08-18

呵呵确实没有DBA

查询计划很简单

这是没有强制索引时的计划,进行了全表扫描,更慢

QUERY PLAN FOR STATEMENT 9 (at line 16).




    STEP 1
        The type of query is SELECT (into Worktable1).
        GROUP BY
        Evaluate Grouped COUNT AGGREGATE.


        FROM TABLE
            K_MS..B_MS
        Nested iteration.
        Table Scan.
        Forward scan.
        Positioning at start of table.
        Using I/O Size 16 Kbytes for data pages.
        With MRU Buffer Replacement Strategy for data pages.
        TO TABLE
            Worktable1.


    STEP 2
        The type of query is SELECT.


        FROM TABLE
            Worktable1.
        Nested iteration.
        Table Scan.
        Forward scan.
        Positioning at start of table.
        Using I/O Size 2 Kbytes for data pages.
        With MRU Buffer Replacement Strategy for data pages.

Table: B_MS scan count 1, logical reads: (regular=503808 apf=63 total=503871), physical reads: (regular=69601 apf=7795 total=77396), apf IOs used=7796
Table: Worktable1  scan count 1, logical reads: (regular=49 apf=0 total=49), physical reads: (regular=0 apf=0 total=0), apf IOs used=0

作者: 75708332   发布时间: 2010-08-18

因为默认没有使用索引
我加了强制LARQ索引
select JBFY,count(JBFY) from K_MS..B_MS(index I_MS_LARQ) where LARQ between @KSSJ and @JSSJ group by JBFY

查询计划如下:
QUERY PLAN FOR STATEMENT 9 (at line 16).




    STEP 1
        The type of query is SELECT (into Worktable1).
        GROUP BY
        Evaluate Grouped COUNT AGGREGATE.


        FROM TABLE
            K_MS..B_MS
        Nested iteration.
        Index : I_MS_LARQ
        Forward scan.
        Positioning by key.
        Keys are:
            LARQ  ASC
        Using I/O Size 16 Kbytes for index leaf pages.
        With MRU Buffer Replacement Strategy for index leaf pages.
        Using I/O Size 16 Kbytes for data pages.
        With MRU Buffer Replacement Strategy for data pages.
        TO TABLE
            Worktable1.


    STEP 2
        The type of query is SELECT.


        FROM TABLE
            Worktable1.
        Nested iteration.
        Table Scan.
        Forward scan.
        Positioning at start of table.
        Using I/O Size 2 Kbytes for data pages.
        With MRU Buffer Replacement Strategy for data pages.


Table: B_MS scan count 1, logical reads: (regular=194688 apf=40 total=194728), physical reads: (regular=164 apf=1604 total=1768), apf IOs used=1604
Table: Worktable1  scan count 1, logical reads: (regular=49 apf=0 total=49), physical reads: (regular=0 apf=0 total=0), apf IOs used=0

能看到索引确实正常使用的,而且IO肯定比全表扫描小
但还是很大啊

作者: 75708332   发布时间: 2010-08-18

强制索引后只有逻辑读比较大。

扫描索引用了逻辑读:(regular=194688 apf=40 total=194728) , 数据只有300万。
平均起来,每个索引页能存储15行记录。感觉要么索引列长度比较大,要么索引没有填充满。

有立案日期的列是否还有其它的比如结案日期、承办部门等列?

考虑:要么针对立案日期和法院编号建立一个索引;
   要么修改已有的包含立案日期的索引,增大填充因子,使得每个索引页能够容纳更多的记录行。那么逻辑读自然就少了。 

作者: andkylee   发布时间: 2010-08-18

可以增加IO的SIZE,减少IO次数

作者: qzwsf   发布时间: 2010-08-19



QUOTE:原帖由 qzwsf 于 2010-8-19 10:59 发表
可以增加IO的SIZE,减少IO次数

那工作量大了。

作者: andkylee   发布时间: 2010-08-19

select FY,count(FY) from K_MS..B_MS where LARQ between @KSSJ and @JSSJ group by FY

如果频繁如此查询,就建一个 LARQ+FY的索引

作者: luckyrandom   发布时间: 2010-08-21

建一个 LARQ+FY的索引应该会好些。建议升级到ase15

作者: 诺华   发布时间: 2010-08-24