タグ付けされた質問 「database-internals」

データベースエンジンの内部動作に関する技術的な質問。

1
削除と切り捨て
コマンドDELETEとTRUNCATEコマンドの違いをより深く理解しようとしています。内部についての私の理解は、次のようなものに沿っています。 DELETE->データベースエンジンは、関連するデータページおよび行が入力されているすべてのインデックスページから行を見つけて削除します。したがって、インデックスが多いほど、削除に時間がかかります。 TRUNCATE ->すべてのテーブルのデータページをまとめて削除するだけで、テーブルの内容を削除するためのより効率的なオプションになります。 上記が正しいと仮定します(正しくない場合は修正してください): さまざまな回復モードが各ステートメントにどのように影響しますか?なんらかの効果がある場合 削除するとき、すべてのインデックスがスキャンされますか、それとも行があるインデックスのみがスキャンされますか?私はすべてのインデックスがスキャンされていると仮定します(シークされませんか?) コマンドはどのように複製されますか?SQLコマンドは各サブスクライバで送信および処理されますか?それとも、MSSQLはそれよりも少しインテリジェントですか?

4
テーブルの定義内の列の順序は重要ですか?
テーブルを定義するとき、論理グループ内の列とグループ自体を目的別に並べると便利です。テーブル内の列の論理的な順序は、開発者に意味を伝え、良いスタイルの要素です。 それは明らかです。 ただし、テーブル内の列の論理的な順序がストレージレイヤーでの物理的な順序に影響を与えるかどうか、または気になるその他の影響があるかどうかは明らかではありません。 スタイルへの影響とは別に、列の順序は重要ですか? これについてStack Overflowに質問がありますが、信頼できる答えがありません。

2
XMLリーダーを使用した計画の最適化
ここからクエリを実行して、デフォルトの拡張イベントセッションからデッドロックイベントを引き出します。 SELECT CAST ( REPLACE ( REPLACE ( XEventData.XEvent.value ('(data/value)[1]', 'varchar(max)'), '<victim-list>', '<deadlock><victim-list>'), '<process-list>', '</victim-list><process-list>') AS XML) AS DeadlockGraph FROM (SELECT CAST (target_data AS XML) AS TargetData FROM sys.dm_xe_session_targets st JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address WHERE [name] = 'system_health') AS Data CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent) …

1
なぜこの述語を探すよりもスキャンが速いのですか?
予期しないものとして説明するクエリパフォーマンスの問題を再現することができました。内部に焦点を当てた答えを探しています。 私のマシンでは、次のクエリがクラスター化インデックススキャンを実行し、約6.8秒のCPU時間を消費します。 SELECT ID1, ID2 FROM two_col_key_test WITH (FORCESCAN) WHERE ID1 NOT IN ( N'1', N'2',N'3', N'4', N'5', N'6', N'7', N'8', N'9', N'10', N'11', N'12',N'13', N'14', N'15', N'16', N'17', N'18', N'19', N'20' ) AND (ID1 = N'FILLER TEXT' AND ID2 >= N'' OR (ID1 > N'FILLER TEXT')) ORDER BY ID1, …

1
SQL Serverの統計は物理的にどこに保存されますか?
クエリオプティマイザーが使用する統計情報は、SQL Serverデータベースファイルとバッファープール内に物理的に保存されていますか? より具体的には、DMVやDBCCを使用して統計で使用されるページを把握する方法はありますか? SQL Server 2008 InternalsとSQL Server Internals and Troubleshootingの両方の書籍を所有していますが、いずれも統計の物理構造については説明していません。もしそうなら、私はこの情報を見つけることができません。

1
同じLOBデータにアクセスする場合、論理読み取りが異なる
同じデータを読み取りながら、非常に異なる論理読み取りを報告する3つの簡単なテストを次に示します。 セットアップ 次のスクリプトは、100個の同一行を持つテストテーブルを作成します。各行には、行外に格納されるのに十分なデータを含むxml列が含まれます。私のテストデータベースでは、生成されるxmlの長さは各行で20,204バイトです。 -- Conditional drop IF OBJECT_ID(N'dbo.XMLTest', N'U') IS NOT NULL DROP TABLE dbo.XMLTest; GO -- Create test table CREATE TABLE dbo.XMLTest ( ID integer IDENTITY PRIMARY KEY, X xml NULL ); GO -- Add 100 wide xml rows DECLARE @X xml; SET @X = ( SELECT TOP (100) …

2
列をNOT NULLからNULLに変更する-内部で何が起こっているのでしょうか?
2.3B行のテーブルがあります。列をNOT NULLからNULLに変更したいと思います。列は1つのインデックスに含まれます(クラスター化インデックスまたはPKインデックスではありません)。データ型は変更されていません(INTです)。ただnullability。ステートメントは次のとおりです。 Alter Table dbo.Workflow Alter Column LineId Int NULL 操作は、停止する前に10を超えます(ブロッキング操作であり、時間がかかりすぎたため、完了まで実行することすらまだできていません)。テーブルを開発サーバーにコピーして、実際にかかる時間をテストします。しかし、NOT NULLからNULLに変換する際にSQL Serverが内部で何をしているのかを誰かが知っているのか興味がありますか?また、影響を受けるインデックスを再構築する必要がありますか?生成されたクエリプランは、何が起こっているのかを示していません。 問題のテーブルはクラスター化されています(ヒープではありません)。

1
ハッシュキープローブと残差
次のようなクエリがあるとします。 select a.*,b.* from a join b on a.col1=b.col1 and len(a.col1)=10 上記のクエリがハッシュ結合を使用し、残差があると仮定すると、プローブキーはにcol1なり、残差はになりますlen(a.col1)=10。 しかし、別の例を見ると、プローブと残差の両方が同じ列であることがわかりました。以下は、私が言おうとしていることの詳細です。 クエリ: select * from T1 join T2 on T1.a = T2.a プローブと残差が強調表示された実行計画: テストデータ: create table T1 (a int, b int, x char(200)) create table T2 (a int, b int, x char(200)) set nocount on declare @i int …

4
ID列のインデックスは非クラスター化する必要がありますか?
ID列を持つテーブルの場合、ID列に対してクラスター化または非クラスター化PK /一意のインデックスを作成する必要がありますか? その理由は、クエリ用に他のインデックスが作成されるためです。非クラスター化インデックス(ヒープ上)を使用し、インデックスでカバーされない列を返すクエリは、余分なクラスター化インデックスBツリーシークステップがないため、使用する論理I / O(LIO)が少なくなりますか? create table T ( Id int identity(1,1) primary key, -- clustered or non-clustered? (surrogate key, may be used to join another table) A .... -- A, B, C have mixed data type of int, date, varchar, float, money, .... B .... C .... ....) create …

2
列サイズが大きくなった後、インデックスの作成に時間がかかるのはなぜですか?
ベンダーは、データベース全体のほとんどすべての列の列幅を変更しました。データベースは約7TB、9000以上のテーブルです。55億行のテーブルにインデックスを作成しようとしています。ベンダーのアップグレードの前に、2時間でインデックスを作成できました。今では数日かかります。彼らが行ったことは、varchar(xx)サイズをvarchar(256)に増やすことです。そのため、ほとんどの列はvarchar(18)またはvarchar(75)などでした。 とにかく、主キーは6列で構成され、幅は合計で126文字でした。アップグレード後、プライマリキーは1283文字になり、SQL Serverの900文字の制限に違反します。テーブルの列全体の幅は、1049の合計varcharカウントから4009の合計varcharカウントになりました。 データの増加はありません。テーブルはすべての列幅が増加する前よりも「スペース」を消費しませんが、インデックスのような単純なものを作成するためのパフォーマンスには不合理な時間がかかります。 列のサイズを大きくすることだけが行われたのに、作成とインデックス作成に非常に長い時間がかかる理由を誰でも説明できますか? pkはクラスター化インデックスであるため、作成しようとしているインデックスは非クラスター化です。インデックスの作成を何度か試みた後、私たちはあきらめました。完了せずに4〜5日間実行されたと思います。 ファイルシステムのスナップショットを取得して非稼働環境でこれを試し、より静かなサーバーでデータベースを起動しました。

2
リーフページと非リーフページの違いは何ですか?
私はいくつかのインデックス使用レポートを実行していますが、LeafとNon-leafの定義を取得しようとしています。リーフと非リーフの両方の挿入、更新、削除、ページ結合、ページ割り当てがあるようです。私は本当にそれが何を意味するのか、または一方が他方よりも優れているかどうかを知りません。 誰かがそれぞれの簡単な定義を提供し、リーフまたは非リーフが重要である理由を説明できれば、それはありがたいです!

1
クラスター化列ストアの非クラスター化インデックスストレージ
SQL Serverでは、行ストアテーブルの一意でない非クラスター化インデックスに、非クラスター化インデックス構造のすべてのレベルでベースオブジェクトのブックマーク(RIDまたはクラスター化キー)が組み込まれます。ブックマークは、すべてのインデックスレベルで非クラスター化インデックスキーの一部として保存されます。 一方、非クラスター化インデックスが一意である場合、ブックマークはキーの一部としてではなく、インデックスのリーフレベルにのみ存在します(実際には、ブックマークは1つ以上の含まれる列として存在します)。 SQL Server 2016では、列指向のテーブル(クラスター化された列ストアインデックスを持つテーブル)に非クラスター化Bツリーインデックスを構築できます。 クラスター化された列ストアテーブルの非クラスター化Bツリーインデックスに使用される「ブックマーク」とは何ですか? 上記の一意および非一意の非クラスタ化インデックスの違いは引き続き適用されますか?

4
PostgreSQL 9.6の列の削除とCTEを使用したSQL関数への副作用
3列(A、B、Dなど)のテーブルがあり、新しい列を導入しなければならなかった場合、Dの現在の位置を置き換えるためにCと言います。次の方法を使用します。 CおよびD2として2つの新しい列を導入します。 Dの内容をD2にコピーします。 Dを削除します D2の名前をDに変更します。 新しい順序は、A、B、C、およびDです。 (これまでのところ)問題が発生しなかったため、これは正当な慣行だと思いました。 しかし、今日、同じテーブルでステートメントを実行する関数が次のエラーを返したときに問題に遭遇しました。 table row type and query-specified row type do not match そして次の詳細: Query provides a value for a dropped column at ordinal position 13 私はPostgreSQLを再起動して、こことここでVACUUM FULL提案されているように最後に関数を削除して再作成しようとしましたが、これらの解決策は機能しませんでした(システムテーブルが変更された状況に取り組むことを除いて)。 非常に小さなデータベースで作業する余裕があったので、エクスポートし、削除してから再インポートしました。これにより、機能に関する問題が修正されました。 ここに見られるように、システムテーブルを変更する(pg_attributeなどで手を汚す)ことによって、列の自然な順序をいじってはならないという事実を知っていました。 Postgresの列の自然な順序を変更することは可能ですか? 私の関数によってスローされたエラーから判断すると、私のメソッドで列の順序をシフトすることもまたノーであることがわかりました。誰が私がやっていることも間違っている理由についていくつかの光を当てることができますか? Postgresバージョンは9.6.0です。 関数は次のとおりです。 CREATE OR REPLACE FUNCTION "public"."__post_users" ("facebookid" text, "useremail" text, "username" text) …

1
varchar(n)のオーバーヘッドは何ですか?
型に関するPostgres docからこのフラグメントの意味を尋ねたいと思いましたvarchar(n)。 短い文字列(最大126バイト)のストレージ要件は、1バイトに実際の文字列を加えたもので、文字の場合はスペースの埋め込みが含まれます。長い文字列には、1ではなく4バイトのオーバーヘッドがあります。 私にはvarchar(255)フィールドがあると仮定しましょう。そして今、次のステートメント: このフィールドが10バイトの文字列を保持する場合、オーバーヘッドは1バイトです。したがって、文字列は11バイトを使用します。 フィールドに140バイトを使用した文字列が含まれている場合、オーバーヘッドは4バイトです。したがって、文字列は144バイトを使用します。 上記のステートメントは真実ですか?ここで誰かが私と同じようにドキュメントを理解していますが、ここでは誰かがオーバーヘッドが常に4バイトであると述べていますか?

4
インデックスの一意性のオーバーヘッド
私はオフィスのさまざまな開発者と、インデックスのコスト、および一意性が有益であるか高価であるか(おそらく両方)について継続的な議論を行ってきました。問題の核心は、競合するリソースです。 バックグラウンド 操作はBツリーのどこに収まるかを暗黙的にチェックし、一意でないインデックスに重複が見つかった場合は、一意化を追加するため、インデックスUniqueを維持するための追加コストはないという説明を以前読んだInsertことがありますキーの終わりですが、それ以外の場合は直接挿入します。この一連のイベントでは、Uniqueインデックスに追加コストはありません。 私の同僚Uniqueは、Bツリー内の新しい位置へのシーク後の2番目の操作として強制されるため、このステートメントに対抗します。したがって、一意でないインデックスよりも維持にコストがかかります。 最悪の場合、テーブルのクラスタリングキーであるID列(本質的に一意)を持つテーブルを見たことがありますが、明示的に非一意であると述べられています。最悪の反対側には、一意性への執着があり、すべてのインデックスは一意として作成されます。インデックスに明示的に一意のリレーションを定義できない場合は、テーブルのPKをインデックスの末尾に追加して、一意性が保証されます。 私は開発チームのコードレビューに頻繁に関与しており、彼らが従うための一般的なガイドラインを提供できる必要があります。はい、すべてのインデックスを評価する必要がありますが、それぞれ数千のテーブルとテーブルに最大20のインデックスを持つ5つのサーバーがある場合、特定のレベルの品質を確保するためにいくつかの簡単なルールを適用できる必要があります。 質問 一意性には、Insert非一意のインデックスを維持するコストと比較して、バックエンドで追加コストがかかりますか?第二に、一意性を確保するためにインデックスの最後にテーブルの主キーを追加することの何が問題になっていますか? テーブル定義の例 create table #test_index ( id int not null identity(1, 1), dt datetime not null default(current_timestamp), val varchar(100) not null, is_deleted bit not null default(0), primary key nonclustered(id desc), unique clustered(dt desc, id desc) ); create index [nonunique_nonclustered_example] on #test_index (is_deleted) include …

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.