3

fooその列にインデックスを持つ、何らかの文字列型のcolumnがあります。SELECTテーブルWHEREからfoo列に接頭辞を付けたいとします'pre'。明らかに、インデックスはここで役立つはずです。

接頭辞で検索する最も明白な方法は次のとおりです。

SELECT * FROM tab WHERE foo LIKE 'pre%';

残念ながら、これはインデックスを使用するように最適化されていません (少なくとも Oracle または Postgres では)。

ただし、以下機能します。

SELECT * FROM tab WHERE 'pre' <= foo AND foo < 'prf';

しかし、これを達成するためのより良い方法はありますか、または上記をよりエレガントにする方法はありますか? 特に:

  • 'pre'からへの関数が必要です'prf'が、これは基になる照合に対して機能する必要があります。'prz'また、例えばを検索する場合、上限はでなければならないなど、上記よりも複雑です'psa'
  • これをストアド関数/プロシージャに抽象化しても、インデックスにアクセスできますか? だから私はのようなものを書くことができます... WHERE prefix('pre', foo);か?

すべての DBMS に対する回答を歓迎します。

4

2 に答える 2

0

ここでデータベースは非常に重要です。たまたま SQL Server が に対してこの最適化を行いlikeます。

1 つの方法は、次のようにすることです。

where foo >= 'pre' and foo <= 'pre+'~'

'~' は、印刷可能な文字の最大の 7 ビット ASCII 値を持つため、基本的に他のどの文字よりも大きくなります。ただし、ワイド文字や非標準の文字セットを使用している場合は、これが問題になることがあります。

通常、関数を使用するとインデックスを使用できなくなるため、これを関数に抽象化することはできません。常に最初の 3 文字を見ている場合、Oracle ではこれらの 3 文字にインデックスを作成できます (「関数ベースのインデックス」と呼ばれるもの)。

于 2013-03-23T22:50:37.093 に答える
-3

どうですか

select * from tab where foo between 'pre' and 'prf' and foo != 'prf'

これにより、同じ方法でインデックスが有効になります。RDBMSは、そのためのインデックスを使用しないようにかなり馬鹿げている必要があります。

于 2013-03-23T23:08:53.090 に答える