3

我有一个查询,它基本上可以在特定日期范围内找到特定项目的 lastcost。

select first 1 lastcost from stock 
where itemid = :itemid and date > :startdate and date < :enddate 
order by date desc

此查询需要几秒钟才能完成数百万条记录,因为“>”不使用索引。如果我按年/月拆分查询并迭代直到它到达开始日期(假设每月有 1 百万条记录)会更快吗?

while (endate > startdate) do
begin
  var_year = extract(year from :endate);
  var_month = extract(month from :endate);
  select first 1 lastcost from stock 
  where itemid = :itemid and year=:var_year and month=:var_month
  order by date desc
  enddate = dateadd (-1 month to enddate);
end

这几天我无法使用firebird,所以我自己也无法尝试。

提前致谢

问候,

雷纳尔迪

4

3 回答 3

4

如果可用于 >、<、>=、<= 和运算符之间,Firebird 会使用索引。

在用这张表发布之前,我做了一个测试:

SQL> show table stock2;
ITEMID                          INTEGER Not Null
STOCKDATE                       TIMESTAMP Not Null
LASTCOST                        DOUBLE PRECISION Nullable

用一些数据填充它(不是每月数百万,但足以测试性能)

SQL> select extract(year from stockdate),
CON>        extract(month from stockdate), count(*)
CON>   from stock2
CON>  group by 1, 2
CON>  order by 1, 2;

EXTRACT EXTRACT        COUNT
======= ======= ============
   2012       1       706473
   2012       2       628924
   2012       3       670038
   2012       4       649411
   2012       5       671512
   2012       6       648878
   2012       7       671182
   2012       8       671212
   2012       9       649312
   2012      10       671881
   2012      11       648815
   2012      12       671579

我运行了您的查询,首先没有任何索引(需要几秒钟),然后仅索引 itemid 列,证明了更好的计划和更好的性能,最后使用了 itemid 和 date 的索引,其中性能要好得多。显示计划允许您查看引擎默认使用索引。

SQL> set plan on;
SQL>
SQL> select first 1 lastcost
CON>   from stock2
CON>  where itemid = 127
CON>    and stockdate > '2012-01-15'
CON>    and stockdate < '2012-03-27'
CON> order by stockdate desc;

PLAN SORT ((STOCK2 INDEX (IDX_STOCK2IDDATE)))

               LASTCOST
=======================
      149.7170031070709

SQL>

我使用的索引定义是:

create index idx_stock2id on stock2 (itemid);
create index idx_stock2iddate on stock2 (itemid, stockdate);
于 2012-12-17T20:57:40.860 回答
1

您可能需要日期的升序和降序索引。

此外,您可以使用“ BETWEEN ”语法:

select first 1 lastcost from stock 
where itemid = :itemid and date between :startdate and :enddate 
order by date desc
于 2012-12-17T07:17:26.093 回答
0

不,循环迭代总是比传统SELECT语句慢。

如果可以,'<' 或 '>' 将使用索引;看看在索引中添加“itemid”是否有帮助

于 2012-12-17T06:58:42.807 回答