タグ付けされた質問 「query-performance」

データベースクエリのパフォーマンスや効率の向上に関する質問。

1
SQL Server-ネストされた非決定的なビュースタック内の文字列のローカライズの処理
私がアクセスされる一部の非決定的関数参照しているビューに出くわしたデータベースプロファイリングしながら、毎分1000から2500回をするために、各このアプリケーションのプール内の接続を。SELECTビューからの単純な結果は、次の実行計画をもたらします。 これは、数か月ごとに1行または2行の変更が発生する可能性がある1000行未満のビューの複雑な計画のようです。しかし、次のその他の遵守事項により悪化します。 ネストされたビューは非決定的であるため、インデックスを作成できません 各ビューは複数UDFのを参照して文字列を作成します 各UDFにはUDF、ローカライズされた言語のISOコードを取得するためのネストされたsが含まれています スタック内のビューは、s から返された追加の文字列ビルダーを述語として使用していますUDFJOIN 各ビュースタックはテーブルとして扱われます。つまり、基礎となるテーブルに書き込むためにそれぞれにINSERT/ UPDATE/ DELETEトリガーがあります。 ビューのこれらのトリガーは、これらの文字列構築をより多く参照CURSORSするEXECストアドプロシージャを使用しますUDF。 これはかなり腐っているように見えますが、TSQLの経験は数年しかありません。それも良くなります! これは素晴らしいアイデアだと判断した開発者UDFは、スキーマ固有の文字列から返された文字列に基づいて、格納されている数百の文字列を翻訳できるように、すべてを実行したようです。 スタック内のビューの1つを次に示しますが、それらはすべて等しく劣っています。 CREATE VIEW [UserWKStringI18N] AS SELECT b.WKType, b.WKIndex , CASE WHEN ISNULL(il.I18NID, N'') = N'' THEN id.I18NString ELSE il.I18nString END AS WKString ,CASE WHEN ISNULL(il.I18NID, N'') = N'' THEN id.IETFLangCode ELSE il.IETFLangCode END AS IETFLangCode ,dbo.User3StringI18N_KeyValue(b.WKType, b.WKIndex, …

6
a = 0およびb = 0および…z = 0 vs a + b + c + d = 0のパフォーマンス
これは簡単な質問ですが、答えが見つからないようです。 パフォーマンスの観点から、のWHEREような条項がある場合a=0 and b=0 and ... z=0、その条件をに置き換えてもパフォーマンスは向上しa+b+...+z=0ますか 言い換えれば、次のものを置き換えることによってパフォーマンスが向上しますか Select * From MyTable Where A=0 and B=0 and C=0 and D=0... と Select * From MyTable Where A+B+C+D=0... 私はそれがインデックスに依存することを知っていますが、この目的のために、インデックスが存在しないとだけ言ってみましょう。算術演算子(+)のパフォーマンスは、「OR」または「AND」論理演算子よりも優れていますか? ANDまたはORを使用した複数の条件よりも、追加の方がパフォーマンスが良いという印象を受けています。 試験結果 420万行のテーブル A = 0、B = 0、C = 0の行を返す-> 351748行 追加(A + B + C = 0)には5秒かかりましたが、論理条件A = 0およびB = 0およびC …

3
SQL Serverの膨大なデータとパフォーマンス
非常に大量のレコードを収集して保存するSQL Serverバックエンドを使用してアプリケーションを作成しました。ピーク時の平均レコード量は、1日あたり30〜40億(20時間の操作)の範囲にあると計算しました。 私の元の解決策(データの実際の計算を行う前)は、クライアントが照会する同じテーブルにアプリケーションがレコードを挿入することでした。明らかに、多くのレコードが挿入されているテーブルをクエリすることは不可能だからです。 2番目のソリューションは、2つのデータベースを使用することでした。1つはアプリケーションが受信したデータ用で、もう1つはクライアント対応データ用です。 私のアプリケーションはデータを受け取り、それを〜10万レコードのバッチにチャンクし、ステージングテーブルに一括挿入します。〜100kの記録後、アプリケーションはその場で、以前と同じスキーマで別のステージングテーブルを作成し、そのテーブルへの挿入を開始します。それは、100kレコードを持つテーブルの名前でジョブテーブルにレコードを作成し、SQL Server側のストアドプロシージャは、ステージングテーブルからクライアント対応の本番テーブルにデータを移動してから、アプリケーションによって作成された一時テーブル。 両方のデータベースには、同じスキーマを持つ5つのテーブルの同じセットがありますが、ジョブテーブルがあるステージングデータベースは例外です。ステージングデータベースには、大量のレコードが存在するテーブルに整合性の制約、キー、インデックスなどがありません。以下に示すように、テーブル名はSignalValues_stagingです。目標は、できるだけ早くデータをSQL Serverにバタンと置くことでした。簡単に移行できるようにテーブルをオンザフライで作成するワークフローは非常にうまく機能します。 以下は、ステージングデータベースからの5つの関連テーブルと、jobsテーブルです。 私が作成したストアドプロシージャは、すべてのステージングテーブルからのデータの移動と本番環境への挿入を処理します。以下は、ステージングテーブルからプロダクションに挿入するストアドプロシージャの一部です。 -- Signalvalues jobs table. SELECT * ,ROW_NUMBER() OVER (ORDER BY JobId) AS 'RowIndex' INTO #JobsToProcess FROM ( SELECT JobId ,ProcessingComplete ,SignalValueStagingTableName AS 'TableName' ,(DATEDIFF(SECOND, (SELECT last_user_update FROM sys.dm_db_index_usage_stats WHERE database_id = DB_ID(DB_NAME()) AND OBJECT_ID = OBJECT_ID(SignalValueStagingTableName)) ,GETUTCDATE())) SecondsSinceLastUpdate FROM SignalValueJobs …

2
更新する行の数に応じて完全に異なるプランを使用するT-SQLクエリ
この質問は、データベース管理者のStack Exchangeで回答できるため、Stack Overflowから移行されました。 7年前に移行され ました。 「TOP(X)」句を含むSQL UPDATEステートメントがあり、値を更新する行には約40億行あります。「TOP(10)」を使用すると、ほぼ瞬時に実行される1つの実行プランが得られますが、「TOP(50)」以上を使用すると、クエリは(少なくとも、待機中ではなく)終了しません。まったく異なる実行計画を使用します。小さいクエリは、インデックスシークとネストされたループ結合のペアを持つ非常に単純なプランを使用します。まったく同じクエリ(UPDATEステートメントのTOP句の行数が異なる)は、2つの異なるインデックスシークを含むプランを使用します、テーブルスプール、並列処理、その他多数の複雑さ。 「OPTION(USE PLAN ...)」を使用して、より小さいクエリによって生成された実行プランを強制的に使用しました。これを行うと、数秒で100,000行も更新できます。クエリプランが良好であることはわかっていますが、SQL Serverは少数の行のみが関係している場合にのみそのプランを選択します。更新でかなり多くの行数があると、最適ではないプランになります。 並列処理のせいかもしれないと思ったのでMAXDOP 1、クエリを設定しましたが、効果はありません-そのステップはなくなりましたが、選択/パフォーマンスの低下はありません。sp_updatestatsそれが原因ではないことを確認するために、今朝も走りました。 2つの実行計画を添付しました-短いものは速いものです。さらに、問題のクエリは次のとおりです(含まれているSELECTが小さい行カウントと大きい行カウントの両方の場合に高速であるように見えることに注意する価値があります)。 update top (10000) FactSubscriberUsage3 set AccountID = sma.CustomerID --select top 50 f.AccountID, sma.CustomerID from FactSubscriberUsage3 f join dimTime t on f.TimeID = t.TimeID join #mac sma on f.macid = sma.macid and t.TimeValue between sma.StartDate and sma.enddate …

5
T-SQLでIFを使用すると、実行計画のキャッシングが弱くなるか壊れますか?
この質問は、データベース管理者のStack Exchangeで回答できるため、Stack Overflowから移行されました。 7年前に移行され ました。 t-SQLバッチでIFステートメントを使用すると、パフォーマンスが低下することが示唆されています。このアサーションを確認または検証しようとしています。SQL Server 2005および2008を使用しています。 アサーションは、次のバッチでのことです:- IF @parameter = 0 BEGIN SELECT ... something END ELSE BEGIN SELECT ... something else END 次の実行には別のブランチが必要な場合があるため、SQL Serverは生成された実行プランを再利用できません。これは、現在の実行で必要なブランチを既に決定できることに基づいて、SQL Serverが実行プランから1つのブランチを完全に削除することを意味します。これは本当ですか? さらに、この場合に何が起こるか:- IF EXISTS (SELECT ....) BEGIN SELECT ... something END ELSE BEGIN SELECT ... something else END どのブランチを実行するかを事前に決定できない場合

3
明確なフローの強制
このようなテーブルがあります: CREATE TABLE Updates ( UpdateId INT NOT NULL IDENTITY(1,1) PRIMARY KEY, ObjectId INT NOT NULL ) 基本的に、IDが増加するオブジェクトの更新を追跡します。 このテーブルのコンシューマーはUpdateId、特定のから順に特定の100個のオブジェクトIDのチャンクを選択しますUpdateId。基本的に、中断した場所を追跡し、更新をクエリします。 私はクエリのみ書き込むことによって最大限に最適なクエリプランを生成することができましたので、これは興味深い最適化問題であることがわかってきましたが起こる私はインデックスのためにやりたいが、ないが保証する私が欲しいもの: SELECT DISTINCT TOP 100 ObjectId FROM Updates WHERE UpdateId > @fromUpdateId @fromUpdateIdストアドプロシージャのパラメーターはどこにありますか。 次の計画: SELECT <- TOP <- Hash match (flow distinct, 100 rows touched) <- Index seek UpdateId使用されているインデックスのシークにより、結果は既に素晴らしく、必要な更新IDの最低から最高まで並べられています。そして、これはフロー別の計画を生成します。それは私が望むものです。しかし、順序は明らかに動作を保証するものではないため、使用したくありません。 このトリックにより、同じクエリプランが得られます(ただし、冗長なTOPがあります)。 WITH …

1
単一行のINSERT…SELECTは、個別のSELECTよりもはるかに遅い
1〜400の番号が付けられた400行の次のヒープテーブルがあるとします。 DROP TABLE IF EXISTS dbo.N; GO SELECT SV.number INTO dbo.N FROM master.dbo.spt_values AS SV WHERE SV.[type] = N'P' AND SV.number BETWEEN 1 AND 400; および次の設定: SET NOCOUNT ON; SET STATISTICS IO, TIME OFF; SET STATISTICS XML OFF; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 次のSELECT文は約6秒で完了します(demo、plan): DECLARE @n integer = 400; …

2
「SELECT TOP」パフォーマンスの質問
selectを使用するtop 100とはるかに高速に実行され、select を使用しないとはるかに低速になるクエリがありますtop 100。返されるレコードの数は0です。クエリプランの違いについて説明したり、そのような違いが説明されているリンクを共有したりできますか。 topテキストなしのクエリ: SELECT --TOP 100 * FROM InventTrans JOIN InventDim ON InventDim.DATAAREAID = 'dat' AND InventDim.INVENTDIMID = InventTrans.INVENTDIMID WHERE InventTrans.DATAAREAID = 'dat' AND InventTrans.ITEMID = '027743' AND InventDim.INVENTLOCATIONID = 'КзРЦ Алмат' AND InventDim.ECC_BUSINESSUNITID = 'Казахстан'; 上記のクエリプラン(なしtop): https://pastebin.com/cbtJpxFf IOおよびTIME統計(なしtop): SQL Server parse and compile time: CPU time = …

2
デフォルトの制約、それだけの価値はありますか?
私は通常、次のルールに従ってデータベースを設計します。 db_ownerとsysadmin以外は誰もデータベーステーブルにアクセスできません。 ユーザーの役割はアプリケーション層で制御されます。通常、1つのdbロールを使用して、ビュー、ストアドプロシージャ、および関数へのアクセスを許可しますが、場合によっては、一部のストアドプロシージャを保護するための2番目のルールを追加します。 TRIGGERSを使用して、重要な情報を最初に検証します。 CREATE TRIGGER <TriggerName> ON <MyTable> [BEFORE | AFTER] INSERT AS IF EXISTS (SELECT 1 FROM inserted WHERE Field1 <> <some_initial_value> OR Field2 <> <other_initial_value>) BEGIN UPDATE MyTable SET Field1 = <some_initial_value>, Field2 = <other_initial_value> ... END DMLは、ストアドプロシージャを使用して実行されます。 sp_MyTable_Insert(@Field1, @Field2, @Field3, ...); sp_MyTable_Delete(@Key1, @Key2, ...); sp_MyTable_Update(@Key1, @Key2, …

2
IS NULL値のフィルター選択されたインデックスが使用されないのはなぜですか?
次のようなテーブル定義があると仮定します。 CREATE TABLE MyTab ( ID INT IDENTITY(1,1) CONSTRAINT PK_MyTab_ID PRIMARY KEY ,GroupByColumn NVARCHAR(10) NOT NULL ,WhereColumn DATETIME NULL ) そして、次のようなフィルター処理された非クラスター化インデックス: CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn ON MyTab (GroupByColumn) WHERE (WhereColumn IS NULL) このインデックスがこのクエリで「カバー」されていない理由: SELECT GroupByColumn ,COUNT(*) FROM MyTab WHERE WhereColumn IS NULL GROUP BY GroupByColumn 私はこの実行計画を取得しています: KeyLookupは、WhereColumn IS NULL述語用です。 計画は次のとおりです。https://www.brentozar.com/pastetheplan/?id …

1
インデックス列の非常に大きなテーブルからのSELECT TOP 1は非常に遅いですが、逆順ではありません(「desc」)
強力なサーバーでSQL Server 2014を実行している約1 TBの大規模データベースがあります。数年はすべてうまくいきました。約2週間前に、次のような完全なメンテナンスを行いました。すべてのソフトウェアアップデートをインストールします。すべてのインデックスを再構築し、DBファイルを圧縮します。ただし、実際の負荷が同じ場合、特定の段階でDBのCPU使用率が100%から150%増加するとは予想していませんでした。 多くのトラブルシューティングを行った後、非常に単純なクエリに絞り込みましたが、解決策が見つかりませんでした。クエリは非常に簡単です。 select top 1 EventID from EventLog with (nolock) order by EventID 常に約1.5秒かかります!ただし、「desc」を使用した同様のクエリには常に約0ミリ秒かかります。 select top 1 EventID from EventLog with (nolock) order by EventID desc PTableには約5億行があります。データ型がbigint(Identity列)EventIDのプライマリクラスター化インデックス列(ordered ASC)です。上部のテーブルにデータを挿入する複数のスレッド(より大きなEventID)があり、下部からデータを削除する1つのスレッド(より小さなEventID)があります。 SMSSでは、2つのクエリが常に同じ実行プランを使用することを確認しました。 クラスター化インデックススキャン。 推定および実際の行番号は両方とも1です。 推定および実際の実行回数は両方とも1です。 推定I / Oコストは8500です(高いようです) 連続して実行した場合、クエリコストは両方で同じ50%です。 インデックス統計を更新しましたがwith fullscan、問題は続きました。インデックスを再構築しましたが、問題は半日消えたようですが、戻ってきました。 IO統計をオンにしました: set statistics io on 次に、2つのクエリを連続して実行し、次の情報を見つけました。 (最初のクエリについては、遅いクエリ) テーブル「PTable」。スキャンカウント1、論理読み取り407670、物理読み取り0、先読み読み取り0、lob論理読み取り0、lob物理読み取り0、lob先読み読み取り0。 (2番目のクエリ、高速クエリの場合) …

3
IF EXISTSでクエリをラップすると非常に遅くなる
私は以下のクエリを持っています: select databasename from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt' and not exists(select 1 from dbo.smalltable c where c.source=l.source) 上記のクエリは3秒で完了します。 上記のクエリが値を返す場合、ストアドプロシージャを終了する必要があるため、次のように書き直しました。 If Exists( select databasename from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt' and not exists(select 1 from dbo.smalltable c where c.source=l.source) ) Begin Raiserror('Source missing',16,1) Return …

3
更新列がインデックスにない更新ステートメントに対するインデックスの影響
私はインデックスが遅くなると人々が言うのを常に見ますupdate、deleteそしてinsert。これは、まるで絶対的なものであるかのように、ブランケットステートメントとして使用されます。 データベースを調整してパフォーマンスを向上させている間、私はこの規則に論理的に矛盾していると思われるこのような状況に出くわします。 SQL Serverでは、他のほとんどのDBMSを使用すると考えられますが、インデックスは指定した特定の列に基づいて作成されます。挿入と削除は常に行全体に影響を与えるため、インデックスに影響を与えることはありませんが、更新はもう少しユニークに見えます。特定の列にのみ影響します。 インデックスに含まれていない列があり、それらを更新する場合、そのテーブル内の他の列にインデックスがあるために、それらは遅くなりますか? たとえば、私のUserテーブルには、1つまたは2つのインデックス、Identity / Auto Incrementカラムであるプライマリキー、および場合によっては外部キーカラム上の別のインデックスがあります。 電話番号や住所など、インデックスのない列を直接更新すると、どちらの状況でもこのテーブルのインデックスが他の列にあるため、この更新は遅くなりますか?更新している列はインデックスにないため、論理的には、インデックスを更新しないでください。どちらかと言えば、WHERE句でインデックスを使用すると、速度が向上すると思います。

1
RECOMPILEクエリヒントを使用する場合のクエリ間の実行時間の著しい違い
同じSQL Server 2005インスタンスで2つのほぼ同一のクエリを実行しています。 最初のSELECTクエリは、LINQによって生成された元のクエリです(私は知っています、私は知っています...私はアプリケーション開発者ではなく、DBAです:)。 2番目のものは最初のものとまったく同じOPTION (RECOMPILE)で、最後にaが追加されています。 他に変更はありません。 最初のものは、実行のたびに55秒かかります。 2番目は2秒かかります。 両方の結果セットは同じです。 このヒントがパフォーマンスの劇的な向上をもたらすのはなぜですか? Books OnlineのエントリにRECOMPILEは、あまり詳細な説明はありません。 クエリの実行後にクエリに対して生成されたプランを破棄するようにSQL Serverデータベースエンジンに指示し、同じクエリが次に実行されるときにクエリオプティマイザにクエリプランを再コンパイルさせます。RECOMPILEを指定しないと、データベースエンジンはクエリプランをキャッシュし、それらを再利用します。クエリプランをコンパイルするとき、RECOMPILEクエリヒントは、クエリ内のローカル変数の現在の値を使用し、クエリがストアドプロシージャ内にある場合、現在の値をパラメータに渡します。 RECOMPILEは、ストアドプロシージャ全体ではなく、ストアドプロシージャ内のクエリのサブセットのみを再コンパイルする必要がある場合に、WITH RECOMPILE句を使用するストアドプロシージャを作成するための便利な代替手段です。詳細については、「ストアドプロシージャの再コンパイル」を参照してください。RECOMPILEは、プランガイドを作成するときにも役立ちます。詳細については、「プランガイドを使用したデプロイ済みアプリケーションでのクエリの最適化」を参照してください。 クエリには多くのローカル変数があるため、OPTION (RECOMPILE)クエリヒントを使用すると、SQL Serverは(真剣に)最適化できると推測されます。 私が見ているところはどこでも、それOPTION (RECOMPILE)は避けるべきだと言っている。この説明は、一般に、このヒントを使用すると、SQL Serverはこの実行計画を再利用できないため、毎回再コンパイルする時間を無駄にする必要があるというものです。(しかし)パフォーマンスが非常に優れていることを考えると、今回はこのクエリヒントを使用するのは良いことだと思います。 使用すべきですか?そうでない場合、このヒントとアプリケーションを変更せずに、SQL Serverにより良い実行計画を使用させることができますか?

2
日付範囲を取得する最も効率的な方法
このようなテーブル構造で日付範囲を取得する最も効率的な方法は何ですか? create table SomeDateTable ( id int identity(1, 1) not null, StartDate datetime not null, EndDate datetime not null ) go との両方の範囲が必要だStartDateとしEndDateます。換言すれば、場合StartDateの間に落ちる@StartDateBeginと@StartDateEnd、とEndDateの間に落ちる@EndDateBeginと@EndDateEnd、その後、何かをします。 これについておそらくいくつかの方法があることは知っていますが、最も推奨されるのは何ですか?

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