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

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

2
一時テーブルは、熱心なスプールよりもハロウィーンの問題に対するより効率的なソリューションであるのはなぜですか?
行がターゲットテーブルにない場合にのみソーステーブルから行を挿入する次のクエリを検討してください。 INSERT INTO dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR WITH (TABLOCK) SELECT maybe_new_rows.ID FROM dbo.A_HEAP_OF_MOSTLY_NEW_ROWS maybe_new_rows WHERE NOT EXISTS ( SELECT 1 FROM dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR halloween WHERE maybe_new_rows.ID = halloween.ID ) OPTION (MAXDOP 1, QUERYTRACEON 7470); 考えられる1つの形状には、マージ結合と積極的なスプールが含まれます。ハロウィーンの問題を解決するために、熱心なスプールオペレーターがいます。 私のマシンでは、上記のコードは約6900ミリ秒で実行されます。テーブルを作成するための再現コードは、質問の下部に含まれています。パフォーマンスに不満がある場合は、熱心なスプールに頼るのではなく、一時テーブルに挿入される行をロードしようとするかもしれません。可能な実装の1つを次に示します。 DROP TABLE IF EXISTS #CONSULTANT_RECOMMENDED_TEMP_TABLE; CREATE TABLE #CONSULTANT_RECOMMENDED_TEMP_TABLE ( ID BIGINT, PRIMARY KEY (ID) ); INSERT INTO #CONSULTANT_RECOMMENDED_TEMP_TABLE …

2
FILESTREAMインサイダー情報の検索
FILESTREAM機能がMicrosoft SQL Server 2012でアクティブになると、SQL Serverはシステム上に「隠された」共有を作成します。共有は次のように定義されます。 Sharename FILESTREAM_SHARE Path \\?\GLOBALROOT\Device\RsFx0320\<localmachine>\FILESTREAM_SHARE Remark SQL Server FILESTREAM share Maximum users unlimited Users Caching Manual caching of documents Permissions NT-AUTHORITY\Authenticated Users, FULL 名前は、SQL Server構成マネージャーで FILESTREAMを最初に構成するときに指定する共有の名前です。しかし、それは何のためですか? これまでのところ 私はすべての利用可能なFILESTREAMドキュメントを以下から読みます。 FILESTREAM(SQLサーバー) FILESTREAMを有効にして構成する FILESTREAM対応データベースを作成する FILESTREAMデータを保存するためのテーブルを作成する ...および関連するすべて FILESTREAMと他のSQL Server機能との互換性 FILESTREAM DDL、関数、ストアドプロシージャ、およびビュー OpenSqlFilestreamを使用してFILESTREAMデータにアクセスする 紙SQL Server 2008の- SQL Server 2008のFILESTREAMストレージ 記事FILESTREAM(OLTP)---他の多くの資料を参照するミッションクリティカルなOLTPソリューションを設計するためのテクニカルリファレンスガイド ...しかし、その共有とその目的、またはその目的についての言及はありませんでした。名前を入力すると、SQL …

2
MySQLでHAVINGがSELECTエイリアスを使用できるのはなぜですか?
私の知る限り、SQLでは、概念的な解釈順序である論理クエリ処理順序は、次のようにFROMで始まります。 から どこ GROUP BY 持っている 選択する ORDER BY このリストに従うと、エイリアスがまだ作成されていないため、WHERE句でSELECTエイリアスを使用できない理由を簡単に確認できます。T-SQL(SQL Server)は厳密にこれに従い、SELECTを渡すまでSELECTエイリアスを使用できません。 しかし、MySQLでは、SELECT句の前に(論理的に)処理する必要がある場合でも、HAVING句でSELECTエイリアスを使用できます。これはどのように可能ですか? 例を挙げると: SELECT YEAR(orderdate), COUNT(*) as Amount FROM Sales.Orders GROUP BY YEAR(orderdate) HAVING Amount>1; ステートメントはT-SQLでは無効です(HAVINGはSELECTエイリアスを参照しているためAmount)... Msg 207, Level 16, State 1, Line 5 Invalid column name 'Amount'. ...しかし、MySQLでは問題なく動作します。 これに基づいて、私は疑問に思っています: MySQLはユーザーを支援するためにSQLルールのショートカットを取っていますか?何らかの事前分析を使用しているのでしょうか? または、MySQLはすべてのRDBMSが従っていたものとは異なる概念解釈順序を使用していますか?

1
ヒストグラム外のカーディナリティー推定
セットアップ カーディナリティの推定値を理解するのに苦労しています。テストのセットアップは次のとおりです。 Stack Overflowデータベースの2010バージョン SQL Server 2017 CU15 + GDR(KB4505225)-14.0.3192.2 新しいCE(互換性レベル140) 私はこのプロシージャを持っています: USE StackOverflow2010; GO CREATE OR ALTER PROCEDURE #sp_PostsByCommentCount @CommentCount int AS BEGIN SELECT * FROM dbo.Posts p WHERE p.CommentCount = @CommentCount OPTION (RECOMPILE); END; GO dbo.Postsテーブルに非クラスター化インデックスまたは統計がありません(にクラスター化インデックスがありますId)。 このための推定プランを要求すると、「推定行」dbo.Postsは1,934.99になります。 EXEC #sp_PostsByCommentCount @CommentCount = 51; 次の統計オブジェクトは、推定プランを要求したときに自動的に作成されました。 DBCC SHOW_STATISTICS('dbo.Posts', [_WA_Sys_00000006_0519C6AF]); そのハイライトは次のとおりです。 統計のサンプルレートは1.81%と非常に低い(67,796 …

1
クエリ実行時の低メモリ状態をシミュレートする方法
低メモリ状態でのSQL Serverの実行エンジンの動作をよりよく理解しようとしています。メモリ付与の観点から言えば、GrantedMemoryに等しくなるように強制する方法があるかどうか疑問に思っていRequiredMemoryます。(私の推測では、それを行うための文書化されていないトレースフラグがあります。誰がそれを知っていますか?)

1
SQL Serverがオブジェクト名とシステムプロシージャに渡される文字列を交換できる理由
オブジェクト名をシステムストアドプロシージャに渡すことが合法である原因は何sp_helptextですか? オブジェクト名を文字列に変換するメカニズムは何ですか? 例えば -- works sp_helptext myproc sp_helptext [myproc] sp_helptext [dbo.myproc] -- and behaves the same as a string sp_helptext 'myproc' sp_helptext 'dbo.myproc' -- does not work sp_helptext dbo.myproc -- Msg 102, Level 15, State 1, Line 1 incorrect syntax near '.' -- an additional case that does not work. …

2
これら2つのSQL Serverロールバックはどのように異なりますか?
SQL Server 2008 R2では、これら2つのロールバックの違いは次のとおりです。 ALTER数分間ステートメントを実行し、「実行のキャンセル」を押します。完全にロールバックするには数分かかります。 同じALTERステートメントを実行しますが、これはLDFファイルが正常に完了するのに十分な大きさでないことを確認します。いったんLDF制限が満たされるとNO「自動拡張」が許されない、クエリの実行はすぐに停止します(またはロールバックが起こる)、このエラーメッセージが表示されて: The statement has been terminated. Msg 9002, Level 17, State 4, Line 1 The transaction log for database 'SampleDB' is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases 次の点で、これら2つの違いは何ですか? 2番目の「ロールバック」が瞬時に行われるのはなぜですか?ロールバックと呼べるかどうかは完全にはわかりません。私の推測では、トランザクションログは実行の進行とともに書き込まれ、タスクを完全に完了するための十分なスペースがないことがわかると、コミットせずに「終了」メッセージで停止します。 最初のロールバックに非常に長い時間がかかるとどうなりますか(ロールバックはシングルスレッドです)。 2.1。SQL Serverは戻って、LDFファイルに作成されたエントリを元に戻しますか? 2.2。LDFファイルサイズは(からのロールバックの終わりに小さくなりますDBCC …

1
スロット配列と総ページサイズ
以下に示すように、多くのフォーラムや多くのブログでページが構成されていることを読み続けています。ページサイズ:16 x 512B = 8192Bページヘッダー:= 96B最大行数行:= 8060B これにより、(8192-96-8060)B = 36Bになります。 わかりました、これは論理的で正しいです。私の質問はこれです。なぜ多くの人が、残りの36Bがスロットアレイ用に予約されていると言うのですか 明らかに、スロット配列はページの行ごとに2Bを提供します。そのため、最小2B、最大1472Bになります。 2B:1行* 2B = 2B 1472B:8096B = n * 9B(オーバーヘッドを伴う最小行サイズ...単一のTINYINT列を考えてください)+ n * 2B(行ごとのスロット配列コスト)=> 8096 = 11n => n = 8096/11 = 736 736 * 2B = 1472B。 14Bバージョンタグにより、これで20になります。 USE master ; GO CREATE DATABASE test ; GO USE test …

1
これらの同様のクエリが異なる最適化フェーズ(トランザクション処理とクイックプラン)を使用するのはなぜですか?
この接続アイテムのサンプルコード バグを示します SELECT COUNT(*) FROM dbo.my_splitter_1('2') L1 INNER JOIN dbo.my_splitter_1('') L2 ON L1.csv_item = L2.csv_item 正しい結果を返します。ただし、次の例では誤った結果が返されます(2014年、新しいCardinality Estimatorを使用) SELECT (SELECT COUNT(*) FROM dbo.my_splitter_1('2') L1 INNER JOIN dbo.my_splitter_1('') L2 ON L1.csv_item = L2.csv_item) L2の結果が共通のサブ式スプールに誤ってロードされ、L1の結果の結果が再生されるためです。 2つのクエリの動作の違いがなぜなのか興味がありました。トレースフラグ8675は、動作search(0) - transaction processingするものが入り、失敗するものが入っていることを示していますsearch(1) - quick plan。 したがって、追加の変換ルールの可用性は動作の違いの背後にあると考えられます(BuildGbApplyまたはGenGbApplySimpleを無効にすると、たとえば修正されるようです)。 しかし、これらの非常によく似たクエリの2つの計画で、異なる最適化フェーズが発生するのはなぜですか?私が読んだことからsearch (0)、少なくとも3つのテーブルが必要であり、最初の例ではその条件は確かに満たされていません。

1
なぜこのストリーム集約が必要なのですか?
このクエリをご覧ください。それは非常に簡単です(テーブルとインデックスの定義、および再現スクリプトについては投稿の最後をご覧ください): SELECT MAX(Revision) FROM dbo.TheOneders WHERE Id = 1 AND 1 = (SELECT 1); 注:「AND 1 =(SELECT 1)は、このクエリが自動パラメータ化されないようにするためのものです。これは問題を混乱させているように感じました。 そして、これがプランです(プランのリンクを貼り付けてください): そこには「トップ1」があるので、ストリーム集約演算子を見て驚いた。1行のみであることが保証されているので、私には必要ないようです。 その理論をテストするために、この論理的に同等のクエリを試しました。 SELECT MAX(Revision) FROM dbo.TheOneders WHERE Id = 1 GROUP BY Id; これがその計画です(計画のリンクを貼り付けてください): 案の定、group by planは、ストリーム集約演算子なしで対応できます。 両方のクエリがインデックスの最後から「後方」を読み取り、「トップ1」を実行して最大リビジョンを取得することに注意してください。 ここで何が欠けていますか? ストリーム集合体は最初のクエリで実際に動作するのですか、それとも排除する必要がありますか(それはオプティマイザーの制限であり、そうではありません)? ちなみに、これは信じられないほど実用的な問題ではないことを認識しています(クエリは両方ともCPUの0ミリ秒と経過時間を報告します)。 上記の2つのクエリを実行する前に実行したセットアップコードを次に示します。 DROP TABLE IF EXISTS dbo.TheOneders; GO CREATE TABLE dbo.TheOneders …

1
SQL Serverは、テーブルのIDENTITY VALUEを物理的にどこに保存しますか?
誰かが私にこの方向を正しい方向に向けてくれることを望んでいます。これが私のこれまでの成果です。 SELECT * FROM sys.identity_columns"last_value"を与えるシステムビューですが、そのビューの定義は内部関数を使用しますIdentityProperty(colName, 'LastValue')-したがって、それは行き止まりです(そこでシステムテーブルからプルしません)。 インターネットのどこでも(私が見た)DBCC IDENT_...コマンドを使用して値を明らかにすることを提案していますが、それでも実際に保存されている場所については暗闇の中に残ります。 そこで、DBCC PAGE(TestDB,1,1325,3)テストハーネスデータベースに対して個々のページを検索し、RESEEDコマンドを使用して値10と12の間で再シードすることにしました。 これを行うには、私は上の進値に気づいたIAM: Header、IAM: Single Page AllocationsとIAM: Extent Alloc Status Slot 1すべてが変わりました。(また、bUse1の値は、それ自体で徐々に変化しますが、とにかく定期的に変化することに気付きました)。 だからもう一つの行き止まりと私はすべてのアイデアからです。他にどこで検索できますか? 私はSQL Server 2014を実行しています。内部知識に対する飽くなき渇望がありますが、これほど理解しにくいものはまだありません。理論的には(絶対値)がどこかに保存され、(ほぼ間違いなく)位置を特定できるはずなので、私の注意を引きました。内部的に保存されたデータ/メタデータの場所を発見する私の探求において、この特定の値は私が特にとらえどころのないものとして私を打つ。私は誰かが一緒に来て私に言うことを推測/望んでいます、あなたはそれを手に入れることができますがDBCC PAGE、間違った場所を見ていました。

3
連結物理操作:実行の順序を保証しますか?
標準SQLでは、aの結果のunion all順序は保証されていません。だから、次のようなもの: select 'A' as c union all select 'B' 任意の順序で2つの行を返すことができます(ただし、実際に知っているデータベースでは、「A」が「B」よりも前になります)。 SQL Serverでは、これは「連結」物理操作を使用した実行計画になります。 連結操作が入力をスキャンし、使用可能なレコードがある入力をすべて返すと簡単に想像できます。しかし、私はウェブ上で次の文を見つけました(ここ): クエリプロセッサは、計画に演算子が表示される順序でこの計画を実行します。最初の計画が一番上で、最後の計画が最後です。 質問:これは実際には本当ですか?これは真実であることが保証されていますか? Microsoftのドキュメントには、入力が最初から最後まで順番にスキャンされるという参照は見つかりませんでした。一方、実行しようとすると、結果は、入力が実際に順番に処理されていることを示唆しています。 エンジンが一度に複数の入力を処理する方法はありますか?私のテスト(定数よりもはるかに複雑な式を使用)は、並列対応の8コアマシン上で実行され、ほとんどのクエリは並列処理を利用しています。

1
特定のテーブルのROW_OVERFLOW_DATAページを一覧表示する
ROW_OVERFLOW_DATAの行があるテーブルのページのリストを取得しようとしています。文書化されていないDMVから割り当てられたページのリストを取得できますが、sys.db_db_database_page_allocationsそのDMVの出力にROW_OVERFLOW_DATAページがリストされていないようです。私が見つけることができない他のDMVはありますか? 最小限、完全、そして(うまくいけば!)検証可能な例: USE tempdb; IF OBJECT_ID(N'dbo.t', N'U') IS NOT NULL DROP TABLE dbo.t; GO CREATE TABLE dbo.t ( rownum int NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED , on_row_data varchar(30) NOT NULL DEFAULT ('on_row_data') , off_row_data varchar(MAX) NOT NULL DEFAULT REPLICATE('A', 20000) --PLENTY BIG ENOUGH! ) WITH (DATA_COMPRESSION = NONE); --not …

2
効率的な範囲集計クエリのためのデータベース?
簡単な例として、次のようなテーブルがあるとします。 seq | value ----+------ 102 | 11954 211 | 43292 278 | 19222 499 | 3843 テーブルには数億のレコードが含まれる可能性があり、次のようなクエリを頻繁に実行する必要があります。 SELECT sum(value) WHERE seq > $a and seq < $b seqインデックスが作成されている場合でも、一般的なデータベース実装は各行をループして、最良の場合の合計を計算します。O(n)ここnで、は範囲のサイズです。 O(log(n))クエリごとに、これを効率的に実行できるデータベースはありますか? ここで説明するように、セグメントツリーと呼ばれるデータ構造に遭遇しました。範囲ツリーまたは間隔ツリーとも呼ばれますが、これらの名前はすべて、データ構造のわずかに異なるバリエーションとして説明されることがよくあります。 しかし、そのようなデータ構造を実装するデータベースに出くわしたことはありません。インメモリ構造の場合、最初から実装するのは簡単ですが、永続化する必要がある場合や、メモリに収まりきらない場合は注意が必要です。これを既存のデータベースの上に実装するための効率的なパターンがある場合、それも役立ちます。 補足:これは追加専用のテーブルではないため、この場合、累積合計を保持するなどの解決策は機能しません。

2
ネストされたループ結合が左結合のみをサポートするのはなぜですか?
クレイグ・フリードマンのブログ「ネストされたループ結合」では、ネストされたループ結合が右外部結合をサポートできない理由を説明しています。 問題は、内部テーブルを複数回(外部結合の行ごとに1回)スキャンすることです。これらの複数のスキャン中に、同じ内部行に複数回遭遇する可能性があります。特定の内側の行が結合していない、または結合しないと結論できるのはどの時点ですか? 誰かがこれを本当にシンプルで教育的な方法で説明してくれませんか? それは、ループが外側のテーブル(R1)で始まり、内側のテーブル()をスキャンすることを意味しR2ますか? とR1結合しない値については、結果セットが()になるようにR2aに置き換える必要があることを理解しています。参加しない場合に値を返すことは、私にとって不可能であるように思われます。理由は、返す値がわからないためです。しかし、それはそれが説明される方法ではありません。またはそれは?NULLNULL, R2R2R1R2 SQL Serverは、実際の最適化でない(そして多くの場合、置き換え)RIGHT JOINでLEFT JOIN、しかし問題は、それはだ理由を説明することで、技術的には不可能NESTED LOOPS JOINに使用する/サポートRIGHT JOINロジック。

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