2017-12-14 26 views
1

これはFirebird 2.5用です。複数列のFirebird SQLインデックス

インデックスが2列、たとえばColAとColBのテーブルTがあります。私がしている場合: SELECT * FROM T WHERE ColA=...、WHERE句はA列にしかないので、FirebirdはColB列にデフォルト値を設定してインデックスを優先しますか、このインデックスを使用することはできませんか?

文脈のビット: 私はdbのアップグレードをしています。ここに私が持っているものがあります:

CREATE TABLE user(
    newid BIGINT NOT NULL, 
    oldid BIGINT NOT NULL, 
    anotherCol INT); 

CREATE INDEX idx ON user(oldid, anotherCol); 

CREATE TABLE order(
    RefUser BIGINT); 

order.RefUserは古いです、私はそれらをnewidに変更する必要があります。 、したがって、インデックス、およびNEWIDの作成をこの時点で

UPDATE order o SET o.refuser = (SELECT u.newid FROM user u WHERE u.oldId = o.refuser); 

、oldidまだユニークであるが、後に単一性にのみ(oldid、anotherCol)のためguarantedすることになります。私はそれがこのクエリを使用してください。

ユーザーテーブルは数百万のレコードであり、注文テーブルは数千万にものぼります。このクエリには1時間以上かかります。私はそれを改善する方法を見たいと思っています(その時間量のために重要なサービスをシャットダウンすることに熱心ではありません)。

+1

この順序で列AとBに索引がある場合、WHEREにAまたはAとBを同時に含む条件が含まれる場合、FBはこの索引を使用しますが、WHERE句にB列のみが存在する場合は索引を使用しません。 –

+0

@Andrej:はいインデックスはA、Bにあり、AのみがWHERE句にあります。だから、あなたはFirebirdがインデックスを使用すると言っているからです...その側からの最適化はありません...ありがとうこの正確な答え! – SoyonsPrecis

+0

@SoyonsPrecisあなたはクエリを準備し、実行プランを読むことができます。そのインデックスが使用されるかどうかは、テーブル内の特定の日付(別名インデックスSELECTIVITY)に従ってFirebirdによって決定されます。しかし、一般的な規則では、複合インデックスは最初の列AまたはA&BまたはA&B&Cなどのサブセットで使用される可能性があります。 –

答えて

3

インデックス統計が最新か、少なくともオプティマイザにとって十分であると仮定すると、Firebirdは複数の列インデックスを使用できます(多くの場合、すべての列がwhere句の一部ではない場合があります) 。唯一の制限は、最初の列(またはインデックスの '接頭辞')に対してのみ使用できるということです。 Firebirdのはwhere oldid = 'something'のためではなく、where anotherCol = 'something'のためにうまくインデックスidxを使用することができます

CREATE INDEX idx ON user(oldid, anotherCol); 

とそう

いいえ、Firebirdは"カラム[anotherCol]のデフォルト値を入力しません"です。インデックス上で範囲スキャンを実行し、接頭辞oldidが一致するすべての行を返します。

技術的には、Firebirdのは、インデックスの値が何かされることを意味し、Firebird for the Database Expert: Episode 1 - Indexesで説明したように列を組み合わせることにより、インデックスキーを作成します。実際の生活の中で火の鳥も接頭辞がそうであるように

0<oldid> 1<anotherCol> : row_id 

例えば(簡略化圧縮)それは単一で0val1 1%のための文字列検索をしていたかのように

0val1 1other1 : rowid1 
0val1 1other2 : rowid4 
0val1 1other3 : rowid6 
0val2 1other1 : rowid2 
... 

where oldid = 'val1'を使用して、Firebirdのは、(0val1 1で始まるすべてのエントリのインデックスを検索しますカラム)。この場合、rowid1、rowid4、rowid6と一致します。

oldidのみで多くのクエリを実行すると、oldidにも単一の列インデックスを作成する方が良いでしょう。このインデックスは小さくなり、レコードを検索するときにトラバースが速くなります。もちろん、欠点は、より多くのインデックスが挿入、更新、および削除にパフォーマンスに影響を与えることです。

Concatenated IndexesUse The Index, Luke)も参照してください。

+0

'インデックスの統計は最新か、少なくともオプティマイザにとって十分です.'サーバがそれを使うかどうかを決定するのは第2の部分だけです:-)統計を最新に保つことは重要ですが、インデックスの選択性彼らが知られているので。何らかの理由でデータが古くなった場合、オプティマイザはまだそれを使用しています。なぜなら、それが分かっていれば、それを更新するだけです:-D –

関連する問題