Upgrade to Pro — share decks privately, control downloads, hide ads and more …

型を合わせとくとデータが多くなっても安心

 型を合わせとくとデータが多くなっても安心

Oda Shinsuke

October 22, 2023
Tweet

Other Decks in Technology

Transcript

  1. 今日のお話し SQL Server の話しです 2012 以前 (~ 2012) 2014 以降

    (2014 ~) 今日詳しく話すのはこっち! 型の不一致で起きる問題の1パターンを紹 介します 今日取り上げるのは文字列型について
  2. 2種類の文字列型 char / varchar 日本語環境で特に意識してなかったら、 MS932 で文字データが格納される char および varchar

    (Transact-SQL) - SQL Server | Microsoft Learn nchar / nvarchar Unicode で文字データが格納される nchar および nvarchar (Transact-SQL) - SQL Server | Microsoft Learn
  3. 今日のお題 create table [受注テーブル] ( [Id] bigint not null primary

    key , [区分] char(1) not null , [伝票番号] varchar(10) not null , constraint [UX_受注テーブル_区分_伝票番号] unique ([区分], [伝票番号]) )
  4. 区分、伝票番号でデータを取得 ① where [区分] = 1 and [伝票番号] = 'JU00000001’

    ② where [区分] = '1' and [伝票番号] = 'JU00000001’ ③ where [区分] = N'1' and [伝票番 号] = N'JU00000001' テーブル定義から抜粋 [区分] char(1) not null [伝票番号] varchar(10) not null
  5. ① 区分に数値 where [区分] = 1 and [伝票番号] = 'JU00000001’

    テーブル定義から抜粋 [区分] char(1) not null [伝票番号] varchar(10) not null 3つの中では、1番ダメなやつ 区分列が暗黙の型変換で数値に変換されて実行される。 区分列の 1文字が全て数値に変換出来るならエラーにならない。
  6. ② 全部型が一致 where [区分] = '1' and [伝票番号] = 'JU00000001’

    テーブル定義から抜粋 [区分] char(1) not null [伝票番号] varchar(10) not null 正解! 全部型が一致してるので問題なし。unique 制約のインデックス も使われる。
  7. ③ 区分に nchar / nvarchar where [区分] = N'1' and

    [伝票番号] = N'JU00000001' テーブル定義から抜粋 [区分] char(1) not null [伝票番号] varchar(10) not null おしい! 暗黙の型変換で、区分列 が nvarchar に変換されて実行さ れる。 文字列型同士の変換なのでエラーにはならない。
  8. 暗黙の型変換って… -- 数値に変換 CONVERT_IMPLICIT(int, [dbkan].[dbo].[受注テーブ ル].[区分],0) = CONVERT_IMPLICIT(int, @1, 0)

    -- nchar に変換 CONVERT_IMPLICIT(nchar(1), [dbkan].[dbo].[受注 テーブル].[区分],0) = @1
  9. 暗黙の型変換でもインデックス有効? SQL Server 2014 以降だと、char / varchar / nchar /

    nvarchar の convert_implicit ではインデックスが効 くようになっています! 公式ドキュメントは未確認! 2012 までは 数値と同じようにテーブルス キャン
  10. 型変換無しのリード/実行時間 (1 row affected) Table '受注テーブル_10000000'. Scan count 0, logical

    reads 3, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0. SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms.
  11. 型変換有りのリード/実行時間 (1 row affected) Table '受注テーブル_10000000'. Scan count 1, logical

    reads 18057, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0. SQL Server Execution Times: CPU time = 1234 ms, elapsed time = 1243 ms.