2011-08-10 1 views
1

グループを含むSQLビューがあります。私は好きなものを使ってビューから選択しようとしています。私が選択している列は索引付けされていますが、SQLは表内のすべての行を含む一時表を作成し、where条件でフィルタリングすることを主張しています。 (遅い)最初にフィルターをかけるにはどうすればいいですか?グループのようなステートメントを使用するときに条件を使用するSQLを取得する方法

ビュー定義

SELECT ListCode, SUM(CASE 
    WHEN ListStatus = 'A' THEN 1 
     ELSE 0 
     END) Active 
FROM ListParticipation 
GROUP BY ListCode 

を選択:ちなみに

SELECT * 
FROM ListParticipationView 
WHERE ListCode like '%ReallyCoolList%' 

、私が始まるワイルドカードなしの基準のように使用する場合は、SQL計画はありませんフィルタリングオクルを表示するグループの要約の前に実行してください。

+0

あなたの本当の解決策は、[多対多の関係](http://www.tekstenuitleg.net/en)であると仮定して、リストを 'LIKE'ステートメントに渡すことです。 /articles/software/database-design-tutorial/many-to-many.html)。 –

答えて

2

条件がSARGableでない、つまりインデックスを使用できません。

比較文字列の先頭に%LIKEを使用すると、テーブルスキャンが保証されます。 SQLは、一致するかどうかを評価するために、すべての行のフィールド全体をチェックする必要があります。

ListCodeが非常に長い文字列の場合は、ルックアップテーブルのPKというintにする必要があります。次に評価することができます:

WHERE Listcode IN (1, 3, 4, 6)インデックスを使用します。

1

最初のワイルドカードによってインデックスが使用されないため、最初にフィルタリングされません。基本的に、それは全体文字列を検索している - そうcharまたはvarchar上のインデックスは通常、最初の文字から始まるので、それはまだ、すべての単一の行を検索している...これはなぜ不思議とほぼ同じになります選択基準が第1列ではなく第2列または第3列に基づいて制限されている場合、複数列インデックスは使用されていません。

あなたがListCode秒(どうやら場合のように)繰り返してきた場合は、ListParticipationテーブルにlistCodeIdとして新しいテーブルのIDを置く、その後、自分のテーブルにそれらを抽出考える(とあまりにもインデックスを交換してください)。十分にスマートなオプティマイザを使用している場合は、指定したワイルドカード文字列に一致するテーブル内のすべてのlistCodeが検索されます(ユニークである必要がありますので一意の制約があります)。fkインデックスを照会するのにlistCodeId 。はるかに演奏する必要があります。

+0

私は実際にインデックススキャンで大丈夫です。 ListCode BY '%ReallyCoolList%' GROUPのようなListParticipation FROM ListCode、SUM(CASE ListStatus = '' THEN 1 ELSE 0 END)アクティブ を選択:私は私の混乱は、私がしなければという事実にあると思いますListCodeこのパフォーマンスは良いです。要約するだけの行を取得した後、グループ化を行う全テーブルスキャンを最初に実行しています。同じ種類の計画を使用するために私が異なって何をする必要があるか分かりません。 – John

+0

あなたはインデックススキャンを取得していない、あなたはテーブルスキャンを取得しています。そして、私はあなたのRDBMSが 'where'述部とビュー内のグループ化された列の間の相関を解決していないと考えています。私はどれくらい彼らがこれを解決することができるかについて、私は上手くいかない。しかし、まだ自分のテーブルに 'ListCode'を引き出すことを勧めています。 –

0

あなたはビューがしばしば悪い考えである理由を学んだことがあります。他のビューを呼び出すと、それはずっと悪くなります。テーブルに直接アクセスするSQL文が高速な場合は、それを使用します。しかし、最初の文字としてワイルドカードを持つ同様のステートメントでwhere節を使用しないでください。使い捨てクエリ以外anythign他のためにこれを行うと、あなたのようなdiffernt技術を使用する必要が示しています。あなたは、フルテキストインデックスを使用する必要が
または

  • デザインを修正するために

    1. youneed

    'test、mytest、another stupid test'などのデータを1つの列に格納し、like節を使用して 'mytest'のすべての値を検索する場合は、テーブルを正規化してデータを正しく格納する必要があります。

    用語を検索しているユーザーがいる場合は、正確な名前(「ロナルドレーガン国立空港」のような長い正式な空港名、「National Airport」の検索可能な名前)代わりに。

    特に理由なく%を前に置いている場合は、それをやめてください。