2009-03-03 3 views
3

私はMSSQLインデックスのデフラグスクリプトを作成しています。特定の種類の索引はオンラインで再構築できますが、他の種類の索引は再構築できません。インデックスにvarchar(max)型の列が含まれているかどうかを確認するにはどうすればよいですか?

クラスタ化インデックスの場合は、テーブルにLOB列が含まれているかどうかを確認するのは簡単ですが、クラスタ化されていないインデックスの場合は、特定のインデックスで扱われるLOB列があるかどうかを具体的に知る必要があります。

これは、以前はdm_db_index_physical_statsのalloc_unit_type_descを調べることで可能でしたが、これはvarchar(max)およびxml型のカラムでは機能しません。

これは自分のデータベースではないので、インデックスが適切かどうかについて議論したくないので、それが存在することを受け入れるだけで、スクリプトができるようにしたいこの状況に対処してください。

これを確認するためにどのような種類のSQLを書けますか?私はすべての関連オブジェクトIDとオブジェクト名がスカラ変数にあると仮定します。

答えて

0

"最大"列の場合、sys.columnsテーブルの長さまたはサイズは-1であるべきだと思います。私の目の前にドキュメンテーションを載せてはいけませんが、これが動作すれば教えてください。

3

最大長のcharまたはnvarcharがある場合は、sys.columnsテーブルにフィールドの適切なシステムタイプID(最大長は-1)を持つエントリがあります。

あなたはVARCHAR(システムタイプID 167)を持っているすべてのインデックスのすべてのIDを見つけたいのであれば、あなたはこれを行うだろう:

select distinct 
    si.* 
from 
    sys.indexes as si 
     inner join sys.index_columns as ic on 
      ic.object_id = si.object_id and 
      ic.index_id = si.index_id 
      inner join sys.columns as sc on 
       sc.object_id = ic.object_id and 
       sc.column_id = ic.column_id 
where 
    sc.system_type_id = 167 and 
    sc.max_length = -1 
+0

ありがとう、私はトリックを行うだろうと思う –

+0

クールな豆。私はそれが-1と長さのものであることを知っていた。 –

0

は、人々に注意してください。 Clustered Indexは、LOBに関しては異なる動物です。私が何を意味するかを見てみましょう。

まず、テストテーブルを設定します。このテストではデータは必要ありませんが、PKとしてクラスタ化インデックス(IndexID = 1)があります。 INCLUDEとしてLOB列を含まないNon Clustered Index(IndexID = 2)もあり、INCLUDEとしてLOB列を含むNon Clustered Indexもあります。ここでは、テスト・セットアップコードはそれでは、LOBを含むインデックスを見つけるためにsys.index_columnsを使用するコードを試してみましょう...

--======================================================================== 
--  Test Setup 
--======================================================================== 
--===== If the test table already exists, 
    -- drop it to make reruns in SSMS easier. 
    IF OBJECT_ID('dbo.IndexTest','U') IS NOT NULL 
     DROP TABLE dbo.IndexTest 
; 
GO 
--===== Create the test table 
CREATE TABLE dbo.IndexTest 
     (
     SomeID  INT IDENTITY(1,1) 
     ,SomeInt INT 
     ,SomeLOB1 VARCHAR(MAX) 
     ,CONSTRAINT PK_IndexTest_Has_LOB 
     PRIMARY KEY CLUSTERED (SomeID) 
     ) 
; 
--===== Add an index that has no INCLUDE of a LOB 
CREATE INDEX IX_Has_No_LOB 
    ON dbo.IndexTest (SomeInt) 
; 
--===== Add an index that has INCLUDEs a LOB 
CREATE INDEX IX_Includes_A_LOB 
    ON dbo.IndexTest (SomeInt) INCLUDE (SomeLOB1) 
; 

です。私は、それはそれを言うことができなかった

object_id name    index_id type type_desc ... 
----------- ----------------- ----------- ---- ------------ ... 
163204448 IX_Includes_A_LOB 3   2 NONCLUSTERED ... 

...ここ

--======================================================================== 
--  Test for LOBs using sys.index_columns. 
--======================================================================== 
select distinct 
    si.* 
from 
    sys.indexes as si 
     inner join sys.index_columns as ic on 
      ic.object_id = si.object_id and 
      ic.index_id = si.index_id 
      inner join sys.columns as sc on 
       sc.object_id = ic.object_id and 
       sc.column_id = ic.column_id 
where 
    --sc.system_type_id = 167 and 
    sc.max_length = -1 
; 

は、上記の実行からの出力です...少しそれを開くためにWHERE句でsystem_type_idをコメントアウトしましたLOBは索引列の1つではないため、Clustered IndexにはLOBが含まれています。このClustered Indexを再構築しようとすると、障害が発生します。インデックスは 列のデータ・タイプテキストの 'SomeLOB1' が含まれているため

ALTER INDEX PK_IndexTest_Has_LOB 
    ON dbo.IndexTest REBUILD WITH (ONLINE = ON) 
; 

メッセージ2725、レベル16、状態2、行1オンラインインデックス操作が はインデックス 'PK_IndexTest_Has_LOB' のために実行することができない、ntext型、イメージ、 varchar(max)、 nvarchar(max)、varbinary(max)またはxml。非クラスタ化インデックスの場合、 列はインデックスのインクルード列になります。クラスタ化インデックスの場合は、 はテーブルの任意の列になります。drop_existingの場合、列 は新規または古い索引の一部である可能性があります。操作はオフラインで を実行する必要があります。レムスRusanu(システムは、私はリンクを投稿できないだろう)への帽子の先端で

...

...我々は少し違うものを試すことができます。すべての索引(クラスタ化、非クラスタ化、またはHEAP)は、アロケーション・ユニットとして表示され、行内データ、行外データおよびLOBも識別します。次のコードでは、LOBが関連付けられたすべての索引が検索されます。

--===== Find all indexes that contain any type of LOB 
SELECT SchemaName = OBJECT_SCHEMA_NAME(p.object_id) 
     ,ObjectName = OBJECT_NAME(p.object_id) 
     ,IndexName = si.name 
     ,p.object_id 
     ,p.index_id 
     ,au.type_desc 
    FROM sys.system_internals_allocation_units au --Has allocation type 
    JOIN sys.system_internals_partitions p  --Has an Index_ID 
    ON au.container_id = p.partition_id 
    JOIN sys.indexes si       --For the name of the index 
    ON si.object_id = p.object_id 
    AND si.index_id  = p.index_id 
    WHERE p.object_id  = OBJECT_ID('IndexTest') 
    AND au.type_desc = 'LOB_DATA' 
; 

これにより、この特定のテストでは次の出力が生成されます。 sys.index_columnsに基づくコードではないobject_idとindex_idによって、Clustered Indexでピックアップされたことに注目してください。

SchemaName ObjectName IndexName   object_id index_id type_desc 
---------- ---------- -------------------- --------- -------- --------- 
dbo  IndexTest PK_IndexTest_Has_LOB 163204448 1  LOB_DATA 
dbo  IndexTest IX_Includes_A_LOB 163204448 3  LOB_DATA 
関連する問題