2

約100万行のテーブルがあり、それに対して次のSQLを実行します。

select * from E where sys like '%,141,%'

実行に2〜5秒かかります(最大10行を返します)。少なくとも10倍高速である必要がありますが、SQL Server 2012で実現できるものですか?

サンプルsys値(sys値の長さの範囲は5〜1000文字):

1,2,3,7,9,10,11,12,14,17,28,29,30,33,35,37,40,41,42,43,44,45,46,47,48,50,51,53,55,63,69,
72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,97,109,110,111,113,117,
119,121,122,123,124,130,131,132,133,134,135,139,141,146

テーブルのDDL:

CREATE TABLE [dbo].[E](
    [o] [int] NOT NULL,
    [sys] [varchar](8000) NULL,
    [s] [varchar](8000) NULL,
    [eys] [varchar](8000) NULL,
    [e] [varchar](8000) NULL,
 CONSTRAINT [PK_E] PRIMARY KEY CLUSTERED 
(
    [o] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
4

4 に答える 4

6

あなたのlike条項が全表スキャンを引き起こしています。

このクエリの即時パフォーマンスが必要な場合は、次のフィールドを含む1対多のテーブルが必要になります。

E_Key  <-- Foreign Key, points to primary key of E table
sys    <-- Each record contains one number, not multiple numbers 
           separated by commas

次に、インデックスを作成sysし、通常のWHERE句を使用できます。

于 2012-10-03T19:16:12.943 に答える
3

テーブルスキーマを変更できない場合は、全文検索を有効にして、テーブルに全文インデックスを作成してから、次の手順を実行できます。

select * from E where CONTAINS(sys, ",141,")
于 2012-10-03T19:23:17.190 に答える
1

LIKE演算子は、SQL Serverが各行をスキャンして探しているデータを探すように強制するため、常に遅くなります。以下は、LIKEの代替手段であり、少しうまく機能する可能性があります(ただし、データはスキャンされます)。

SELECT * FROM E WHERE CHARINDEX(',141,', sys) > 0
于 2012-10-03T19:19:25.397 に答える
1

これは古い投稿だと思いますが...

非正規化されたデータをテーブルに格納することに完全に夢中になっている場合は、少なくともインデックスを作成できるように、XMLに変換してください。

ただし、最善の方法は、データを1対多のルックアップテーブルに分割して正規化することです(robert Harveyが上記で提案したように)。

于 2013-02-25T23:12:59.030 に答える