3

特定の日付範囲で特定のアイテムの lastcost を基本的に検索するクエリがあります。

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

">" はインデックスを使用しないため、このクエリは何百万ものレコードで完了するのに数秒かかります。年/月ごとにクエリを分割し、startdate に達するまで反復すると (1 か月あたり 100 万レコードを想定して) 高速になりますか?

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 と日付によるインデックスを使用して、パフォーマンスがはるかに優れていることを確認しました。ショー プランでは、エンジンがデフォルトでインデックスを使用していることを確認できます。

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 に答える