2026年5月24日日曜日

Windows11で標準で入っている画面録画ツール

Windowsでは画面を録画するツールが標準で入っていて、Windows11ではこのツールが増えたので、このツールのメモ。

Windows10では、[Windows]+Gで起動できるGame Barというツールがあり、これが録画ツールでした。
ただ、このツールでは、アプリを録画することはできるけど、デスクトップを録画することはできません。
多分全画面表示を使うゲームやブラウザを録画することを目的としているのでしょう。
Game Barでデスクトップ全体を録画するには、以下のようなアプリで、デスクトップ全体を1つのアプリと見立てて、そのアプリを録画するといったことが必要でした。
そのアプリというのは、リモートデスクトップ接続や、Hyper-V 接続や、Windows サンドボックスなどなどです。

このようにGame Barで単にデスクトップを録画したいとした場合には、ひと手間が必要でした。


で、ここからが本題です。
もともと、Windows8の時代から標準で[Snipping Tool]という画面キャプチャ―ツールが入っていました。
このツールは、スクショを取るツールですが、[prt scr]キーとは違い、キャプチャしたあとに簡単な編集もできるものでした。
このツールがWindows11から、録画もできるようになりました。
上のウィンドウのカメラのアイコンは従来通りのスクショモードのもので、その隣の射影機のアイコンが動画モードとなります。 その隣が切り取り領域を指定するアイコンで、録画モードの時は「四角形」か「ウィンドウ」を選ぶことができます。 四角形にしてもウィンドウにしても録画開始時のデスクトップ上の矩形領域を指定するもので、録画中にそのウィンドウを動かすと背景のデスクトップが映り込みます。 一番左の新規+を押すと、録画領域指定が始まり、領域指定が終わると「スタート」、マイクアイコン、システムオーディオアイコンを含むウィンドウが現れます。 「スタート」を押すと録画開始のカウントダウンが3から始まります。 マイクアイコンでは、マイク音声を録画に含めるかミュートするか選べます。 システムオーディオアイコンはでは、録画中にPCが出力する音を録画に含めるかミュートにするか選べます。 スタートを押すと、スタートだった部分が、一時停止アイコンと停止アイコンに変わります。 停止を押すと動画のトリムができるようになり、トリム機能で保存の時間範囲を指定できます。保存すれば動画が保存されます。 その他の動画編集は「Clipchamp」というアプリでするようです。 Snipping Toolの録画で新規を押す部分までのショートカットは[Windows]+[Shift]+Rです。 注意点として、1時間録画しても30分ぐらいしか録画できなかったことがあったこと、 録画中に(20分ぐらい経過したときに)とくに連絡なく突然SnippingToolが落ちることがあること EventViewerでは、クラッシュとのこと。
クラッシュは、音声入力が問題のなのかもしれないが、SnippingToolの録画時間は10分程度のものにしておいた方がよい気がする。 Snipping Toolでは、さらに、選択した範囲をテキストに起こすOCRみたいなこともできるようになったみたいです。

2026年5月23日土曜日

Amazonのセールの条件が戻った?

次回のAmazonのセールの条件が今回は元に戻ったみたい。
さて、次々回はどうかな?

2026年4月25日土曜日

Amazonの客層評価が変った?

アマゾンのセールは、今まで1万円を超えたらポイントアップするものだったけど、
今回のSmileセールからは2万円をこえたら、となってしまいました。
どうやら人によってここの値段が違うらしい。 1万円にもどるまで、セールでの購入は自粛かな。

2025年12月6日土曜日

Profilerから特定のSQL実行プランの調査方法

来週必要になりそうなので操作メモ。
Profilerで実行プランを採取する設定、トレースファイル出力する形で採取開始。
所定のSQLを実行 トレースを停止する。
トレースファイルをダブルクリックしてSQL Profilerを起動し編集する。
トレースファイル設定時に5MByteでロールオーパする設定をしていたので、以下ダイアログがロールオーバー分表示される。全部[はい]を選択。
プロパティで表示する行、列を絞り込む
このダイアログで、タブ切り替えをして
この画面で、必要なイベント(行)、項目(列)を絞り込む
次に列フィルタで実行プランに特定のキーワードが入っているもののみに絞り込む。今回は「7067」のキーワードにしてみる。
またロールオーパファイルの指定があるので、すべて「はい」を選択。
絞り込まれたデータが意図通りか1つ内容確認をしてみる。
よければ、全行を選択しコピー(Ctrl+C)する。
excelに貼り付ける。
絞り込みの結果、ShowPlanイベントの場合、B列がtextDataとしていたので、内容はShowplanXMLとなっている。
このExcelを渡して解析してもらえばいいかな。xlsxなら、zip圧縮ファイルなのでテキストデータは効率よく圧縮してくれるはず。 この段階で、実行プランのビジュアル化は不要だと思うけど、必要な場合は、B列の1セルの内容をテキストエディタに貼り付けて、 拡張子を.sqlplan、文字コードをBOMつきUTF-8で保存すると、 その.sqlplanファイルをダブルクリックすれば、SSMSが立ち上がり実行プランをグラフィックで表示できる。
追記:上でProfilerの結果をExcelに貼り付けたが、実行プランはXMLなので実行プランでは文字数が33000文字を超えることはざらにある。 Excelの1つセルに入れられる文字の最大数は32,767文字なので、はみ出した文字は次の行の先頭セルに入れられてしまう。 これでは、1列目はイベント種類ということが言えなくなり、実行プランファイルを作るには、2つのセルの内容を連結して作らなければならない。 うまくいかないものですね。 Profilerで実行プランのイベントを抽出する設定をした場合に追加される以下の[イベント抽出の設定]タブでXMLプランを個別にファイルに出力した方がよさそう。 ただ、何十個の実行プランを1ファイルに保存すると、この.sqlplanファイルを開いたときにSSMSが固まるので、実行プランごとにファイルに分ける設定ができる。 この設定をすると(トレースファイルのロールオーバーのように)ファイル名の拡張子の前に_連番が付加される。 (下のダイアログでは、aa.sqlplan,aa_1.SQLPlan,aa_2.SQLPlan,...,aa_10.SQLPlan,...となる)

2025年11月29日土曜日

同じSELECT文の構造同士でデッドロックエラーが出る現象

前回の記事で、SELECTでインデックスの絞り込みが甘いせいでデッドロックが発生した記事を書いたけど、
その現象の一例について記事化しておく。


pubsデータベースのsalesテーブルを使って解説。
pubsデータベースのトランザクション分離レベルはREAD_COMMITTED。
salesテーブルは、主キーが、stor_id,ord_num,title_idとなっているクラスター化インデックステーブル。
salesテーブルにstor_id='7067'のデータは4件あり、このうち2件に対して、rowlockとupdlockのヒントをつけてselectをする。
(rowlockはロックエスカレーションを起こさないため、updlockは、この後の更新で変換デッドロックを起こさないためにつけている。)

2つのトランザクションから同じ構造のselect文を2回発行する。(トランザクションをTrAとTrBと書く。)
TrAとTrBで発行するのはそれぞれ以下のSQL。

select * from sales with(rowlock,updlock)
where stor_id='7067' and title_id='TC4203'

と、

select * from sales with(rowlock,updlock)
where stor_id = '7067' and title_id='TC3218'

まず、TrAでselectを実行する。(下図の左の選択部分を実行した結果)
実行できて、1行結果が返ってくる。
次に、TrBでselectを実行する。(下図の右の選択部分を実行した結果) 検索実行待ちとなる。
次にTrAで、2回目のselectを実行する。(下図の左の選択部分を実行した結果) TrAは結果が返ってきて、TrBは待ちとなっていたselectがデッドロックエラーとなる。
では解説。 まず、TrAで1つ目のSELECTをした結果1行返ってきた時点で、このトランザクションのこの行に更新ロックがかかる。 トランザクション分離レベルが何であっても更新ロックの生存期間はトランザクション終了までである。 次に、TrBでSELECTをした結果、(店番に対してのみの)クラスタ化インデックスキーシークを行う。 このときに、店番で見つけたレコードに対して、更新ロックをかけ中身を見ようとする。 (ロックの役割上ロックをかけられなればそのレコードの中身を見れない。) TrAで取得していない行をロックしつつ、 TrAで取得した行をロックをしようとしたときに、更新ロック同士は互換性がないため、 TrAのロックの開放待ちとなり、中身が見れない状態となる。 この行の内容が検索条件にヒットするのかヒットしないのかわからない状態のため、SELCT自体のTrBも実行中(ロック解除待ち)となる。 次に、TrAの2つ目のSELECTをした結果、TrBでロックされている行をロックすることができず、その行の中身が見られない。(ロック解除まち)となる。 結果、TrAとTrBが互いのロック解除待ちとなりデッドロックが成立する。 ここで、TrBが検索結果をまだ返していないのにもかかわらずTrAとのデッドロックの原因となることから、 たとえupdatelockつきselectが1回のみのトランザクション同士でも、そのトランザクション同士が同時に起動した場合にデッドロックが起こりうることになる。 どんだけやっても1つのselect文だけでは2つのトランザクション間でデッドロックが発生しなかった。 この辺のロックの詳細仕様はSQL Server内部の仕様となり不明。 (例えば、ロックする行の順番など仕様として決めてしまうとマルチプロセスで処理をする場合の足かせになってしまうので、仕様を定めていないと思います。) 今回の実験ではデッドロックとなりましたが、実行順序を変えた場合以下のようになり、ロックは発生するがデッドロックは起きませんでした。 TrBで1つ目のSELECT→1行返ってくる。 TrAで1つ目のSELECT→実行中となる。 TrBで2つ目のSELECT→1行返ってくる。 TrBでCOMMIT→TrAで1行返ってくる。(TrBのロック待ちが解除された) TrAで2つ目のSELECT→1行返ってくる。 TrAでCOMMIT→正常完了。 で、インデックスで対象の行が絞り込まれ、絞り込まれた先には他のトランザクションのロックがかかっていない場合は、このデッドロックの現象を回避できる。 というわけで、、前回の記事のように、 salesテーブルにstor_id,title_idを持つインデックスixを作り、 TrAとTrBから同じ構造のselect文を2回発行する。 TrAとTrBで発行するのはそれぞれ以下のSQL。 select * from sales with(rowlock,updlock,index(ix)) where stor_id='7067' and title_id='TC4203' と、 select * from sales with(rowlock,updlock,index(ix)) where stor_id = '7067' and title_id='TC3218' まず、TrAでselectを実行する。(下図の左の選択部分を実行した結果) 実行できて、1行結果が返ってくる。
次に、TrBでselectを実行する。(下図の左の選択部分を実行した結果) 実行できて、1行結果が返ってくる。
次にTrAで、2回目のselectを実行する。(下図の左の選択部分を実行した結果) 実行できて、1行結果が返ってくる。
次にTrBで、2回目のselectを実行する。(下図の左の選択部分を実行した結果) 実行できて、1行結果が返ってくる。

2025年11月24日月曜日

SQL Server Profilerの使用は非推奨?

SQL Serverでupdlock,rowlockヒント付きの同じselect文同士で、デッドロックが発生した。
デッドロックエラー時の実行プランをみたところ、4列からなる主キーのうち、シークキーとしているのが1列のみ。
理由は、select文のwhere句に指定があるのは、主キーの第1,3,4番目の列で、主キーの第2番目の列を指定していないため。
別に用意されていた(where句の検索条件で十分絞り込まれる)2次インデックスは使われていなかった。

対応として、(たとえSQL Serverが計算したコストが高くなっても)2次インデックス使うようにするヒントを追加する対応をする。

で、効果確認で、実行後にプランハンドルを検索し実行プランを抽出しようとしたが、
検索に手間取りプランハンドル特定時には実行プランが流れて(消えて)しまっていた。

なので、SQL Profilerを仕込んで、SQLを実行することにしようとしたが、netを見ると、profilerの使用は非推奨となっており、
拡張イベントを使う方法が推奨とのこと。

というわけで、SQL Profilerと拡張イベントでの実行プランの採取方法の備忘録。


まずは、profilerの方法
Microsoft SQL Server Tools→SQL Server Profiler を起動し、新しいトレースを押し、

サーバへの接続ダイアログで、該当サーバに接続し、 トレースのプロパティダイアログで、[全般]タブでは、使用するテンプレートでStandard(default)のまま、 [イベントの選択]タブで、すべてのイベントを表示するにチェックボックスをONにした後、
Performance→Showplan XML Statistics Profileの行にチェックを入れて実行ボタンを押下。
調査するSQL文の実行が終わった後に、赤い四角アイコン(選択したトレースの停止)を押して、トレース採取完了。 EventClassがShowplan XML Statistics Profileの行を選択すると、SQLPlanが図示される。 次に拡張イベントの方法 SQL Server Management Studioでサーバへの接続ダイアログで、該当サーバに接続し、 オブジェクトエクスプローラーウィンドウでSQL Server→管理→拡張イベント→セッションを右クリックし新しいセッションウィザードを選択。
ウィザード(ステップ式ダイアログ入力)で [セッションのプロパティの設定]ステップで、セッション名を指定し、
[テンプレートの選択]ステップで、テンプレートにStandardを選択し、
[キャプチャするイベントの選択]ステップで、query_post_execution_showplanイベントを追加し、
[グローバルフィールドのキャプチャ]ステップと、 [セッションイベントフィルターの設定]ステップはデフォルトのまま [セッションデータストレージの指定]ステップで、SQLサーバー上のファイル名を指定して(SQL Serverへのログインユーザの次第では書き込み権限がないかも。)完了ボタンを押下。
成功のダイアログを閉じる。
オブジェクトエクスプローラーウィンドウでSQL Server→管理→拡張イベント→セッションを展開すると、ウィザードステップ1でしていしたセッション名が赤四角(停止中)で表示される。
右クリック→[セッションの開始]すると、赤い四角から、緑の右向き三角となり採取中となる。
最後に、今回の対応での実行プランの見方をpubsデータベースsalesテーブルを使って解説。 salesテーブルは、主キーが、stor_id,ord_num,title_idとなっているクラスター化インデックスキーとなっている。 salesテーブルにstor_id,title_idを持つインデックスixを作ってみる。
SQL Server Management Studioで[実際の実行プランを含める(Ctrl + M)]をした後、 select * from sales where stor_id='6380' and title_id='BU1032' を実行し、実行プランを見ると、SELECTはクラスター化インデックスシークを行っていることがわかる。
クラスター化インデックスシークをポイントすると、シークキーにstor_idのみ使われていることがわかり、
SELECTをポイントすると、サブツリーの推定コストが、0.0032842とわかる。
次に、select * from sales with(ixndex(ix)) where stor_id='6380' and title_id='BU1032' を実行し、実行プランを見ると、SELECTは[sales].[ix]のインデックスシークと、[sales].UPKCL_salesのキー参照をNested Loops(入れ子ループ)でインナージョインしていることがわかる。
インデックスシークでは、シークキーに、stor_idと、title_idが使われており、
SELECTでは、サブツリーの推定コストが、0.0065704とわかる。
つまり、with(index(ix))のヒントにより、SQL Serverは、推定コストが0.0032842ではなく、それより大きい0.0065704の実行プランを採用していることがわかる。 これで、デッドロックの解消ができればいいんだけれど。