SQLserver設計メモ

DBサーバを一台新設する事になりました。

 

要件をヒアリングしたところ”基本的な設定は既存DBと同じで”との事。

フムフムそれじゃ簡単かな?と思ってドキュメントを探してみたら・・・・・・ない。

インストール時の選択内容しか残されていない。

 

「え、もしかして全部デフォで動いてるの??まさか(笑)(笑)」

と実機を確認した所、どうやらファイルサイズ以外はホントにデフォみたいで・・・

 

そういう訳で、一般的にはどういうポイントがあるのだろう?と調べて見ることにしました。

 

■メモリ

まずは既存DBで逼迫しているメモリについて。

サーバー メモリの構成オプション

min server memory の既定の設定は 0 MB で、max server memory の既定の設定は 2,147,483,647 MB (中略) 詳細については、「動的メモリ管理」を参照してください。

 

いやいや最大2ペタて。無制限に確保する感じかな…詳細についてはこっちか。

動的メモリ管理

メモリを動的に使用する場合、 SQL Server はシステムに定期的にクエリして、メモリの空き容量を確認します(中略)空きメモリが少ない場合、 SQL Server は OS に対してメモリを解放します。 

今回は、構築時にSQLServer入れる直前のメモリ使用状況を確認して、

安全率だけちょっと見込んで設定する方向で進めようと思います。

 

 

もうひとつ、これは各所で「絶対やるべき」とオススメされていました

Lock Pages in Memory (LPIM)

プロセスを使用して物理メモリにデータを保持できるアカウントを指定し、ディスク上の仮想メモリへのデータのページングを防止します。 メモリ内のページをロックすると、ディスクへのメモリのページングが発生した際に、サーバーの応答性を維持できます。

 

が、

という事みたいです。下手に設定するとマズイという事でしょうか。

 

SQLserverのプロセスが使用するメモリを物理メモリにロックするという事は、

別のプロセスが使える物理メモリは当然減少する訳で、

そしてSQLserverが使用するメモリはデフォルトで2ペタである訳で。

動的メモリ管理でちゃんと増減してくれるようですが、こういう言う風にも書いてある訳で。

Lock Pages in Memory ユーザー権利を使用するとき、上記のように max server memory の上限を設定することが推奨されます。

LPIMだけ有効にするのは危ないようですね。

 

 

■ファイル

データファイルの配置はそれぞれ環境毎の要件があるかと思うので割愛。

それ以外で、知らなかったけど有効そうなものを見つけました。

tempdb データファイル数を CPU 数に一致させる

一般的には、tempdb データファイルの数は、SQL Server が使用可能な CPU の数に一致させた方が高負荷時のパフォーマンス劣化を防ぐことができるとされています。

tempdb 負荷が高いのか低いのか分からないのであれば、やっておいた方が無難でしょう。

はい。やってみます。スケジューラ(=CPUコア数)に合わせましょう、という事らしいです。

ちなみにtempdbがどういう時に使われるのかというと。

SQL Serverインスタンスが内部で利用する一時領域「TEMPDB」とはhttps://www.atmarkit.co.jp/ait/articles/1610/06/news013.html

 

サブクエリとかインラインビュー、ORDERBYの結果とかが含まれるのでしょうか。

 

そのほか、実効性は状況次第と思われるが試してみたい手法がいくつかありました。

  1. データとインデックスのデータファイルを分ける
  2. ログファイルは分割しない
  3. ファイルの自動拡張は基本ナシ。するならサイズベースで、同時拡張。

1は、物理レコード削除が頻繁に発生するなら効果がありそうに思います。

2と3はお作法のようです。ファイルI/Oの効率向上が見込めるようです。

 

 

■MaxDOP

並列処理可能な実行プランの最大値、だそうです。これだけ読んでもよく解りませんでした。

max degree of parallelism サーバー構成オプションの構成

並列プラン実行で使用するプロセッサの数を制限できます。 SQL Server では、クエリ、インデックス データ定義言語 (DDL) の操作、並列挿入、オンライン列変更、並行統計コレクション、静的およびキーセット ドリブン カーソルの作成の場合に並列実行プランが検討されます。

 

ますますわからん…ですが、注意事項の記載内容を見ると

セットアップで実施するようになったという事は、重要なオプションという事なのでしょうね。

このオプションは詳細設定オプションであるため、熟練したデータベース管理者または認定された SQL Server プロフェッショナルだけが変更するようにしてください。

あまりほいほいと弄るものでもないようです。

とあるサイトではCPUコアの1/4が推奨とされていたのですが、弊社環境だと1になってしまいます。

並列処理しない、というのはとてもとてもマズイ事に思えるので、今回は見送り。

2019の試用版インストーラを起動してみて推奨値だけ確認してみる、というのもアリでしょうか。

 

 

これらを元に、来週(忙しかったら再来週)に環境構築予定です。

 

 

■今回拝見させて頂いたサイト様

いつも勉強させて頂いてます。ありがとうございます。

 

 

■読み飛ばしてもいい感想文

メモリ制限は、一応OSの邪魔はしないように、っていう方針ではある様子。

とはいえ、ギリギリまで確保しては「ごめんなさい!お返しします!」っていうのも、

却ってオーバーヘッドになりそうな感じがします。

世の皆様も明示を推奨されている項目でした。

 

 

ディスクに関していうと、昔は特に物理ディスクを意識したI/O性能検討

(内周と外周、アクセスヘッドの移動)がなされてました。

今でも構成によっては有効だと思います(テスト用の単体物理サーバとか)が、

昨今のエンタープライズ用DBサーバはだいたいFCでストレージと繋がっていると思います。

その場合はいきなりディスクに書くのではなく、入り口の大きなキャッシュメモリとやり取りしますし、

実際のディスク書き込みでもRAID構成、それらを束ねて論理的に見せる仮想ボリュームなど、

物理ディスクの事はほぼ気にしなくていいのが現状かと思います。

 

インストール先とかデータファイルパスをCドライブにしない、とかは当たり前と言われてますが。

今やシステムソフトウェアインストール用のドライブ分けに意味を持たせるには、

個別でリストア可能という利点を活かせる運用が前提です。

OSやミドルの設定をいじってもバックアップしないのであれば、(そしてそういう会社は多い)

最初から全部Cドライブでいいんじゃない?と思います。

前述のように昔はI/O分散の意味もあったでしょうが、SANブート環境では無意味ですし。

 

 

どれをとってみても感じるのは、内部動作を深く掘り下げないと効果的なチューニングは難しい、

という事ですね。まだまだ学びの道は続きます。

 

SQLserverでコマンドプロンプトからSQLを実行する

今週は弊課に新人がいらっしゃいました。

その為、システム利用に関するユーザー追加依頼がチラホラとありまして。

 

中でもちょっと面倒だなと思ったのが、SQLserverのユーザ追加。

管理中のシステムにおいて、DB(全部SQLserver)接続ユーザは個人別になっており、

ユーザの立場によって割り当てる権限(ロール)が決まっています。

私はそれを付与する立場です。

何が出来るか出来ないか、私の指先一つです。ふひひ。

 

 

大きく3つ(本番環境、結合環境、単体環境)に区分される環境に、

それぞれ数台ずつのDBサーバ(1サーバ1インスタンス)、

各インスタンスにはいくつかのデータベース。

ユーザの立場によって使うデータベースはバラバラ。

 

今回は急かされたのもあっていつもどおりにSSMSで接続して作業してたのですが、

コマンドラインでパパパっと出来るんじゃないのかー、と思って調べてみました。

 

 

■SQLCMD

そういう訳でSQLCMDです。

sqlcmd ユーティリティを使用すると、Transact-SQL ステートメントやシステム プロシージャ、スクリプト ファイルを使用可能なさまざまなモードで入力できます。

  • コマンド プロンプト。
  • クエリ エディターでの SQLCMD モード。
  • Windows スクリプト ファイル。
  • SQL Server エージェント ジョブのオペレーティング システム (Cmd.exe) ジョブ ステップ。

このユーティリティでは、ODBC を使用して、Transact-SQL バッチを実行します。

利用前提環境

Windows インストーラー 4.5 と Microsoft ODBC Driver for SQL Server 17 の両方が必要です。

私のPCにはSQLserverを入れてるのですが、ODBCドライバは入って無い状態でした。

インストールで躓く事は特にないと思います。

 

■使ってみる

コマンドプロンプトを起動して SQLCMD と叩くだけ。

管理者モードで起動する必要もなく、パスも通してくれてます。

 

じゃあなんか適当にSQLを実行してみようかと

あれ。

どうやったら実行出来るんだろ?まだDBに繋がっていないとかかな?DB変えてみよ。

あっ

 

なるほど。goで実行、そういえばそうでしたね。

 

うんうん。

 

 

抜けるときはgo不要です。

 

さて、別サーバに接続するには…

-H -U -P あたりでしょうか。

 

 

来週出社したら試してみたいと思います。

 

余談ですが、SQLserverでサーバとかインスタンスとか言うとややこしいですね。

発言者のバックボーンによって、何を指してるのかが違ったりして…

 

XLOOKUP関数を使ってみた

前々から興味あったXLOOKUP関数を使ってみました。

 

結論から言うと、どこかで見かけた情報から勝手に想像していたものとは違いました。

それでも、確実にVLOOKUPより汎用的になったと思います。

 

簡単なお試し結果を書いてみます。

 

 

 

■まずは適当に表を用意

インフラSEらしくサーバ一覧的な感じのものを。

 

 

 

■パターン1:VLOOKUPの弱点をちょっと克服

XLOOKUP関数の引数は以下の通りです。

 

 

このようにXLOOKUPでは「検索する列」と「戻り値の列」をバラバラに指定できます。

 

 

「検索値は検索範囲の先頭列に無ければならない」

この制約の為だけに、情報が揃ってる表を弄る必要が無くなるようです。

 

 

また、検索値がヒットしなかった場合、これまではエラーが戻されていましたが、

エラー戻り値を指定出来るようになりました。

 

 

文字列貼り付けしてからの、こういう地味な手間も不要になる訳ですね。

 

 

 

■弱点克服について確認

では実際に何か入れてみます。

入力した式と戻り値はこういう感じです。

まずはオーソドックスに「完全一致、前から検索」です。

 

 

結果はこの通り。

所謂VLOOKUPですが、検索不一致の結果が意図した文字列になっています。

 

 

式選択時の表示はこんな感じです。VLOOKUPだと範囲選択は1枠ですよね。

 

 

ブログ書いてる途中で気付いたので、一致モードの「2」も試してみました。

結果がわかりやすいよう後ろから検索で。

 

 

結果はこの通り。

一応ワイルドカード検索も普通に出来るようです。

・・・あれ?VLOOKUPでも出来たような気がしますねあせる
 

 

 

 

■複数データを戻す

続いてVLOOKUPでは出来なかった機能ですが、こっちが目玉になるでしょうか。

戻り値に複数列が指定して、検索値にヒットした行から指定列全部の値を引き出せます。

 

式の中身はこんな感じです。戻り値列にA~D列を指定しています。

 

 

そして、結果がこちら。

このように、該当列の情報を一気に拾ってこれます。

 

 

 

この画像だけ見ると「各列で個別に値を取得」しているように見えますが。

ここでVLOOKUP脳とオサラバしなくてはなりません。

 

 

といっても今回のXLOOKUPにまつわる新機能ではないのですが。

スピルという機能によって、あるセルに入力された式の戻り値が複数列(配列)の場合、

必要な分だけ自動で式の範囲が拡張されるようになっています。

実際に式を入力したのは”分類”を示す値のセルだけで、

後のセルには勝手に式を入力してくれました。(式はグレーアウト表示されます)

 

ちなみに、スピルについてはコチラのサイトで紹介されていました。

 

 

 

■試してみての感想

実は、結構ガッカリしています(笑)

IFSやCOUNTIFSの様に、条件を複数設定出来る機能だと思いこんでいたので・・・

 

複数列を戻してくれるのも一見便利ですが、要らない列まで戻されてしまうケースも多そうです。

飛び飛びの列で戻り値を指定、は試してみましたが出来ませんでした。

 

VLOOKUP相当の使い方が基本になって、列順序が非対応の場合のみ、

XLOOKUPを使う事になりそうな気がします。対応バージョンの問題もありますし。

 

 

今の所は、VLOOKUPがちょっと便利になった程度の印象です。