ハロの外部記憶インターフェイス

そろそろ覚える努力が必要かも…

SQL Serverで外部ファイルをコマンドライン実行する

外部ファイルをコマンドラインから実行

サンプル db_nameに接続し、script.sqlを実行し、処理結果をscript.logファイルに出力する。

sqlcmd -U "sa" -P "password" -S "localhost" -d db_name -i script.sql -o script.log

サーバー認証の場合、-E

sqlcmd -S "localhost" -E -d db_name -i script.sql -o script.log

直接SQL文を実行する場合

sqlcmd -S "localhost" -E -d db_name  -Q "select getdate(); -o script.log
  • -qと-Qの違いQの場合、処理後、SQLCMDを終了する。

複数ファイルを実行する場合、カンマ具切りつなぐだけ

sqlcmd -S "localhost" -E -d db_name -i script1.sql,script2.sql,script3.sql -o script.log

ログ・ファイルを追記にする

sqlcmd -S "localhost" -E -d db_name  -Q "select getdate(); >> script.log

SQL ServerのManagement Studioでは早いがアプリケーションで実行すると遅くなる

Management Studioでのクエリ実行とPGの中での実行の違い

主に遅い原因は実行プランの違い、問題はなぜ違いが発生するかだが、原因としてManagement Studioでの実行とPGでの実行ではPGで頻繁に実行されるとSQLが再利用される。実行プランも再利用されるため、データによっては遅くなる場合がある。(らしい)

  • ARITHABORTがManagement StudioではデフォルトONだが、PG実行時はデフォルトOFFになっている。

PGのSQL実行時に意図的にONにしてあげると、早くなる場合あり。(効果なしの場合も多い)

SET ARITHABORT ON
-- 実行SQL 
SET ARITHABORT OFF

SQL文のエンコーディング問題

PGからSBサーバーへ送られるクエリのエンコーディングによっては以下の問題が発生しているみたい。varcharのほうが圧倒的多いはずだし、なんとかMSが頑張ってほしいな

  • SQL ServerではvarcharがSJIS、nvarcharがUnicode扱い
  • SQLがnvarcharとして実行されてた場合、varcharカラムに対して暗黙的にキャストが行われるらしい

インデックス断片化調査

SQL Serverびインデックス断片化の調査

とりあえず30%以上だったら、最高値を検討しよう

SELECT a.index_id, name, avg_fragmentation_in_percent  
FROM sys.dm_db_index_physical_stats (DB_ID(N'DbName'), NULL, NULL, NULL, NULL) AS a  
    JOIN sys.indexes AS b 
      ON a.object_id = b.object_id AND a.index_id = b.index_id
WHERE avg_fragmentation_in_percent > 30
GO  

インデックス再構成

断片化が30%未満の場合、再編成でも大丈夫らしい

ALTER INDEX IDX_INDEX1 
  ON DbName.TableName
REORGANIZE ;   

テーブルの全インデックス再構成

ALTER INDEX ALL ON DbName.TableName
REORGANIZE ;  

インデックス再構築

断片化が30%以上の場合、再構築が有効

ALTER INDEX IDX_INDEX1 
  ON DbName.TableName
REBUILD ;   

テーブルの全インデックス再構築

ALTER INDEX ALL ON DbName.TableName
REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON,
              STATISTICS_NORECOMPUTE = ON);

REBUILD WITH (ONLINE = ON) ;

インデックスの再構成と再構築の違い

再構築がひとつのトランザクションでインデックスを完全に再作成するのに対して、再構成は処理単位ごと (処理単位はページ) にトランザクションが分割されていて、リーフページ間でインデックス行を移動させることで行を前に詰めて断片化を解消しているという点

  • 再構成(REORGANIZE)
  • 再構築(REBUILD)
    • 現在のインデックスはそのままで新しいインデックスを作成する。(DBのデータファイルが新しいインデックス分容量が増える)
    • 完了までがトランザクションになるため、途中で止めた場合、全てロールバックになる。
    • 完了まではインデックスが2つ存在する状態

参考: https://blogs.msdn.microsoft.com/jpsql/2013/02/28/977/ https://docs.microsoft.com/ja-jp/sql/relational-databases/indexes/reorganize-and-rebuild-indexes

SQL ServerにOracleにリンクサーバーを設定する。

SQL ServerORACLEへのリンクサーバ設定

ORACLE用リンクサーバーを作成する。

以下のスクリプトより、リンクサーバーを作成する。

USE [master]
GO
EXEC master.dbo.sp_addlinkedserver 
 @server = N'ORA_LINK',              -- リンクサーバー名
 @srvproduct=N'Oracle',              -- プロダクト名 特に意味はなさそう
 @provider='OraOLEDB.Oracle',  -- 固定
 @datasrc='ORCL'                        -- tnsnames.oraに設定したSIDを設定する。
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'collation compatible', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'data access', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'dist', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'pub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'rpc', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'rpc out', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'sub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'connect timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'collation name', @optvalue=null
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'lazy schema validation', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'query timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'use remote collation', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'ORA_LINK', @optname=N'remote proc transaction promotion', @optvalue=N'true'
GO
USE [master]
GO
EXEC master.dbo.sp_addlinkedsrvlogin 
  @rmtsrvname = N'ORA_LINK', 
  @locallogin = NULL , 
  @useself = N'False', 
  @rmtuser = N'scott',      -- ORACLEのログインユーザID
  @rmtpassword = N'tiger'  -- ログインパスワード
GO

接続確認処理

以下のSQLの結果として1が表示されれば成功

SELECT * FROM OPENQUERY(ORA_LINK,'SELECT 1 D FROM DUAL')

トラブルシューティング

サードパーティOracle プロバイダを使用していて、その Oracle プロバイダを SQL Server プロセス外部で実行できない場合、プロバイダ オプションを変更してインプロセスで実行できるようにします。 * ManagementStudioから「サーバーオブジェクト\リンクサーバー\プロバイダ」からOraOLEDB.Oracleをダブルクリックし、InProcess許可をチェックいれる。

参考: https://support.microsoft.com/ja-jp/help/280106/how-to-set-up-and-troubleshoot-a-linked-server-to-an-oracle-database-i

Ubuntu 16.04でgolangのVS Code開発環境設定が上手くいかない

golang用のVS Code環境設定

golangの開発環境として、VS Codeを利用するため設定を行ったが、以下のエラーになった

dlv:
Error: Command failed: /usr/bin/go get -u -v github.com/derekparker/delve/cmd/dlv
github.com/derekparker/delve (download)
github.com/derekparker/delve/pkg/dwarf/reader
# github.com/derekparker/delve/pkg/dwarf/reader
src/github.com/derekparker/delve/pkg/dwarf/reader/variables.go:81: vrdr.dwarf.Ranges undefined (type *dwarf.Data has no field or 

以下のサイトを参考に手動インストールを試みるが delve/install.md at master · derekparker/delve · GitHub

$ go get -u github.com/derekparker/delve/cmd/dlv
package github.com/derekparker/delve/cmd/dlv: cannot download, $GOPATH not set. For more details see: go help gopath

エラーになった。

原因

golangのバージョン問題で1.6ではdebugger用パッケージがインストールされないみたいだったので、 golangをバージョンアップして、再度やってみたら解決した。

Ubuntuのgolang環境を1.9へアップグレードする。

現在のgolangバージョンを確認

Ubuntu 16.04 にはv1.6がインストールされているみたい

$ go version
go version go1.6.2 linux/amd64

とりあえず、golang1.9をインストールする。

$ sudo apt install golang-1.9

インストールは成功するものの、golangのバージョンは変わらない

調べて見ると同じ現象で悩んでいた人を発見 http://blog.panicblanket.com/archives/4278

$ ls /usr/lib | grep go
go
go-1.6
go-1.9
gold-ld

確かに1.9はインストールされていた。

早速シンボリックリンクを再設定

cd /usr/bin
sudo mv go go_16
sudo mv gofmt gofmt_16
sudo ln -s /usr/lib/go-1.9/bin/go /usr/bin/go
sudo ln -s /usr/lib/go-1.9/bin/gofmt /usr/bin/gofmt

無事golang 1.9になった

$ go version
go version go1.9.2 linux/amd64