继续 - 在查询完成之前查看FIRST_ROWS

时间:2010-04-05 05:17:20

标签: sql sql-server database oracle informix

我已经确定了我的用户通常使用的查询结构。我是否有必要创建复合索引来支持这些构造并提供FIRST_ROWS功能?

如果我从SE迁移到IDS,我将失去使用C-ISAM调用编写低级函数的能力,但是获得FIRST_ROWS以及其他好处,例如:用于索引扫描的SET-READS(onconfig USE_ [KO] BATCHEDREAD ),优化程序指令,并行查询等。


来自评论的信息

  

通过以下方式查询典当行生产表:customer.name char(30)使用通配符(LAS SUR F *查找LASTNAME SURNAME,FIRSTNAME)或通过pawns.ticket_number INT查询。客户和典当的加入方式为:customer.name = pawns.name,而不是customer.serial = pawns.fk。具有超过1年的trx日期的典当被移动到另一个硬盘上的不同数据库中的历史表(> 500K nrows)。历史索引是通过trx_date降序。这是ad-hoc复合查询构造发挥作用的地方。

     

一旦找到客户的典当交易,当客户进行兴趣或兑换pymt时,该行将被更新。如果客户在90天内没有制作pymt,用户将手动更新他们将丧失的手册。当客户赎回一个棋子或因缺乏pymt而没收它时,pawns.status会变为非活动状态。当他们的trx日期超过1年时,非活动状态会从典当表中移出到历史表中,因此此应用程序中不会发生批量更新。当铺开业时,典当行每天早上都会进行这个过程。

{ISQL 2.10.06E (SE-DOS16M protected mode) pawns table optimization - 
 once-daily, before start of business, procedure}

 unload to "U:\UNL\ACTIVES.UNL"
    select * from pawns where pawns.status = "A"
  order by pawns.cust_name, pawns.trx_date;

 unload to "U:\UNL\INACTIVE.UNL"
    select * from pawns
     where pawns.status <> "A"
       and pawns.trx_date >= (today - 365)
  order by pawns.cust_name, pawns.trx_date desc;

 unload to "U:\UNL\HISTORIC.UNL"
    select * from pawns
     where pawns.status <> "A"
       and pawns.trx_date < (today - 365)
  order by pawns.trx_date desc;

 drop table pawns;

 create table pawns
 (
     trx_num serial,
     cust_name char(30),
     status char(1),
     trx_date date,
 . . . ) in "S:\PAWNSHOP.DBS\PAWNS";

 load from "U:\UNL\ACTIVES.UNL" insert into pawns;         {500:600 nrows avg.}
 load from "U:\UNL\INACTIVE.UNL" insert into pawns;        {6500:7000 nrows avg.}
 load from "U:\UNL\HISTORIC.UNL" insert into dss:historic; {>500K nrows}

 create cluster index pa_cust_idx on pawns (cust_name);

 {this groups each customers pawns together, actives in
  oldest trx_date order first, then inactive pawns within the last year in most 
  recent trx_date order. inactives older than 1 year are loaded into historic 
  table in a separate database, on a separate hard disk. historic table 
  optimization is done on a weekly basis for DSS queries.}

 create unique index pa_trx_num_idx on pawns (trx_num);
 create index pa_trx_date_idx on pawns (trx_date);
 create index pa_status_idx on pawns (status);

 {grant statements...}

 update statistics;

1 个答案:

答案 0 :(得分:1)

没有一个简单的是/否答案 - 这是一个平衡行为,就像许多性能问题一样。

与索引相关的主要成本有两个必须与收益相平衡。

  1. 在表中添加,删除和修改行时,必须维护索引。成本并不大,但也不算微不足道。
  2. 索引占用磁盘空间。
  3. 在优化查询时,由于需要考虑更多索引,因此开销也很小。

    良好索引的主要好处是,当索引可以有效使用时,可以大大提高选择数据的性能。

    如果您的表不是非常易变,并且经常使用索引可以帮助的条件进行搜索,那么创建复合索引可能是有意义的,假设磁盘空间不是问题。

    如果你的表非常不稳定,或者很少使用某个特定的索引(但在使用它的那几个场合是有益的),那么你应该权衡一个较慢的查询的几乎一次性成本与在可以使用的情况下,为少数情况存储和维护索引的成本。

    关于索引设计的主题有一本非常好的书:Lahdenmäki和Leach的Relational Database Index Design and the Optimizers(它也相当昂贵)。


    在最新评论中,弗兰克说:

      

    [L]为一些事情做了一些事情。正如已经说过的那样,最简单的做法是允许Informix在拥有它们后开始返回行。 (默认情况下,Oracle会这样做。)弗兰克所要求的更大图片与谷歌的相似之处。好吧,当谈到网络上的搜索索引时,它真的可以追溯到Alta Vista和90年代。我们的想法是,您可以快速搜索,在报告搜索中返回的“数量”行的同时获取前n个内容。 (好像Google报告的数字是准确的。)

    Frank的这个额外评论在这个问题的背景下更有意义。

    显然,除非SQL语句强制Informix进行排序,否则只要有结果就会使结果可用;它总是有。 FIRST_ROWS优化提示向IDS表明,如果它可以选择两个查询计划,并且一个将让它比另一个更快地生成第一行,那么它应该更喜欢快速生成第一行的那个,甚至如果它总体上比替代品更昂贵。即使没有提示,IDS仍然会尽快使数据可用 - 它也试图尽可能高效地完成数据。

    当准备好查询时,您可以估计可以返回多少行 - 您可以将其用作指标(少数,非常多,非常多)。另外,您可以快速独立地发现要搜索的主表中的行数。给定此元数据,您当然可以使用带滚动游标的技术在数据库中为您提供后备存储,其中包含您感兴趣的行的主键值。您可以随时使用显示数据加载数组用于显示给用户的一组有趣的行。根据用户请求,您可以安排显示另一个充满信息的页面。在程序的某个时刻,您会发现您已经到达滚动光标中的数据末尾。很明显,如果你做了最后一次FETCH,那么就强迫它发生。如果你再做一些FETCH NEXT,那么你最终会得到一个NOTFOUND条件。

    自80年代后期以来,所有这一切都可以通过Informix(IDS及其先前版本,OnLine,Turbo,SE和I4GL)实现。 FIRST_ROWS优化是最近的;它仍然只是优化器的一个提示,通常对优化器的作用没什么影响。