none
DO's&DONT's #2: 絶対にやらなければいけないこと - データ型を一致させる 前編 RRS feed

  • 質問

  • DO's&DONT's #2: 絶対にやらなければいけないこと - データ型を一致させる 前編

    https://social.technet.microsoft.com/Forums/ja-JP/41ee9e02-9176-45b2-ab89-707aba9c38b5/dosdonts-2-?forum=jpbidp

    DO's&DONT's #2: 絶対にやらなければいけないこと - データ型を一致させる 後編

    https://social.technet.microsoft.com/Forums/ja-JP/06fd4597-897e-4d54-974e-90abb3e91bbd/dosdonts-2-?forum=jpbidp  

    ( 2012 5 6 日に Microsoft SQL Server Japan Support Team Blog に公開した情報のアーカイブです。)

    神谷 雅紀 SQL Server Eascalation Engineer

    クエリを書く場合、比較を行うデータのデータ型は一致させておくことが必要です。

     

    なぜ?

    データ型が一致していない場合、必ず、どちらかのデータがもう片方のデータのデータ型に変換された後に比較が行われます。つまり、SQL Server は、データ型変換という余分な処理を行わなければならなくなります。また、それだけではなく、データ型を一致させるために、本来読み取る必要のないデータを読み取らなければならなくなることもあります。

     

    どのような影響があるのか?

    クエリのパフォーマンス悪化です。比較するデータのデータ型が一致していない場合、データ型の優先順位に従って、優先順位の低いデータ型のデータが、優先順位の高いデータ型に変換されます。

     

    データ型の優先順位 (Transact-SQL) http://msdn.microsoft.com/ja-jp/library/ms190309.aspx

     

    例えば、以下のクエリを考えます。

     

    CREATE TABLE TableA (C1 varchar(10)) GO SELECT * FROM TableA WHERE C1=N'XXX' GO

     

    SELECT の WHERE 句に指定されている C1 は VARCHAR(10) ですので非 Unicode 型ですが、比較対象の N’XXX’は Unicode 型です。

    この場合、何が発生するのでしょう?実行プランを見てみます。

     

    |--Table Scan(OBJECT:([testdb1].[dbo].[TableA]), WHERE:(CONVERT_IMPLICIT(nvarchar(10),[testdb1].[dbo].[TableA].[C1],0)=[@1]))

     

    CONVERT_IMPLICIT() が入っています。これは、その名のとおり、暗黙のデータ型変換です。データ型が異なっているため、データ型を一致させる処理が必要になります。

    もし、データ型が一致していたら、どうでしょうか?

     

    SELECT * FROM TableA WHERE C1='XXX'

     

    当然、データ型変換は不要になります。

     

    |--Table Scan(OBJECT:([testdb1].[dbo].[TableA]), WHERE:([testdb1].[dbo].[TableA].[C1]=[@1]))

     

    これは単純な例ですが、実際には、データ型を変換するためには、変換対象のデータを一旦読み取り、データ型を変換し、データを比較という処理が必要になるため、インデックスによる絞込みを効率的に行うことができず、著しくパフォーマンスが悪化することがあります。

     

    どのように対応するか?

    データ型を一致させます。

     (つづく)


    2019年3月28日 10:57
    所有者