我有一个查询,它基本上可以找到特定日期范围内某个项目的最后成本。
select first 1 lastcost from stock
where itemid = :itemid and date > :startdate and date < :enddate
order by date desc
此查询在数百万条记录上需要几秒钟才能完成,因为“&gt;”不使用索引。 如果我按年/月分割查询并迭代直到达到startdate(假设每月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
我无法在这几天使用火鸟,所以我自己也没试过。
提前致谢
此致
Reynaldi
答案 0 :(得分:4)
Firebird使用索引(如果可用于&gt;,&lt;,&gt; =,&lt; =以及运算符之间。
我在用这张表发布之前做了一个测试:
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的索引,其中性能更好。 show plan允许您在默认情况下看到引擎使用索引。
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);
答案 1 :(得分:1)
日期可能需要升序和降序索引。
此外,您可以使用“BETWEEN”语法:
select first 1 lastcost from stock
where itemid = :itemid and date between :startdate and :enddate
order by date desc
答案 2 :(得分:0)
不,带循环的迭代总是比传统的SELECT
语句慢。
和'&lt;'或'&gt;'如果可以,将使用索引;看看是否将'itemid'添加到索引帮助