タグ付けされた質問 「cardinality-estimates」

1
SQL Server 2014:一貫性のない自己結合カーディナリティの推定値についての説明はありますか?
SQL Server 2014の次のクエリプランを検討してください。 クエリプランでは、自己結合ar.fId = ar.fIdにより1行の推定値が得られます。しかし、これは論理的に矛盾する推定値は、次のとおりar有する20,608行とのちょうど1つの異なる値fId(正確に統計に反映します)。したがって、この結合は行(~424MM行)の完全な外積を生成し、クエリを数時間実行します。 SQL Serverが統計と矛盾していることが非常に簡単に証明できる見積もりを思い付く理由を理解するのに苦労しています。何か案は? 初期調査と追加の詳細 ここでのPaulの回答に基づくと、結合のカーディナリティを推定するためのSQL 2012とSQL 2014の両方のヒューリスティックは、2つの同一のヒストグラムを比較する必要がある状況を簡単に処理できるようです。 トレースフラグ2363からの出力から始めましたが、それを簡単に理解できませんでした。以下は、SQL Serverがためにヒストグラムを比較していることを意味スニペットないfIdとbIdだけその用途に参加の選択を推定するためにfId?もしそうなら、それは明らかに正しくないでしょう。または、トレースフラグの出力を読み間違えていますか? Plan for computation: CSelCalcExpressionComparedToExpression( QCOL: [ar].fId x_cmpEq QCOL: [ar].fId ) Loaded histogram for column QCOL: [ar].bId from stats with id 3 Loaded histogram for column QCOL: [ar].fId from stats with id 1 Selectivity: 0 完全な再現スクリプトに含まれ、このクエリをミリ秒にまで下げるいくつかの回避策を思いついたことに注意してください。この質問は、動作の理解、今後のクエリでの動作の回避方法、およびMicrosoftに提出する必要があるバグかどうかの判断に焦点を当てています。 ここで完全なREPROスクリプトは、ここにあるトレースフラグ2363年からフル出力は、ここであなたがすぐにいっぱいスクリプトを開くことなく、それらを見たい場合はクエリとテーブル定義は次のとおりです。 …

2
SQL Server 2014でLEN()関数がカーディナリティを過小評価するのはなぜですか?
文字列列と特定の長さの行をチェックする述語を持つテーブルがあります。SQL Server 2014では、チェックする長さに関係なく、1行の推定値が表示されます。実際には数千または数百万の行があり、SQL Serverはこのテーブルをネストされたループの外側に配置することを選択しているため、これは非常に貧弱な計画を生み出しています。 SQL Server 2012で31,622行を見積もる一方で、SQL Server 2014の1.0003のカーディナリティの見積もりについての説明はありますか?良い回避策はありますか? 問題の簡単な複製を次に示します。 -- Create a table with 1MM rows of dummy data CREATE TABLE #customers (cust_nbr VARCHAR(10) NOT NULL) GO INSERT INTO #customers WITH (TABLOCK) (cust_nbr) SELECT TOP 1000000 CONVERT(VARCHAR(10), ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) AS cust_nbr FROM master..spt_values v1 CROSS …

2
サブクエリが行の推定値を1に減らすのはなぜですか?
次の不自然な単純なクエリを検討してください。 SELECT ID , CASE WHEN ID <> 0 THEN (SELECT TOP 1 ID FROM X_OTHER_TABLE) ELSE (SELECT TOP 1 ID FROM X_OTHER_TABLE_2) END AS ID2 FROM X_HEAP; このクエリの最終的な行の推定値は、X_HEAPテーブル内の行数に等しいと予想されます。サブクエリで何をしていても、行を除外できないため、行の推定値は重要ではありません。ただし、SQL Server 2016では、サブクエリが原因で行の推定値が1に減少しています。 なぜこれが起こるのですか?私はそれについて何ができますか? 適切な構文でこの問題を再現するのは非常に簡単です。これを実行するテーブル定義のセットを次に示します。 CREATE TABLE dbo.X_HEAP (ID INT NOT NULL) CREATE TABLE dbo.X_OTHER_TABLE (ID INT NOT NULL); CREATE TABLE dbo.X_OTHER_TABLE_2 …

2
LIKE演算子のカーディナリティの推定(ローカル変数)
私はLIKE、未知のシナリオのすべての最適化で演算子を使用する場合、レガシーと新しいCEの両方が9%の見積もりを使用するという印象を受けました(関連する統計が利用可能であり、クエリオプティマイザーが選択性の推測に頼る必要がないと仮定)。 クレジットデータベースに対して以下のクエリを実行すると、CEごとに異なる推定値が得られます。新しいCEでは、予想していた900行の見積もりを受け取りますが、レガシーCEでは、241.416の見積もりを受け取りますが、この見積もりがどのように導出されるのかわかりません。誰もが光を当てることができますか? -- New CE (Estimate = 900) DECLARE @LastName VARCHAR(15) = 'BA%' SELECT * FROM [Credit].[dbo].[member] WHERE [lastname] LIKE @LastName; -- Forcing Legacy CE (Estimate = 241.416) DECLARE @LastName VARCHAR(15) = 'BA%' SELECT * FROM [Credit].[dbo].[member] WHERE [lastname] LIKE @LastName OPTION ( QUERYTRACEON 9481, QUERYTRACEON 9292, QUERYTRACEON 9204, QUERYTRACEON …

2
連結演算子が入力よりも少ない行を推定するのはなぜですか?
次のクエリプランスニペットでは、Concatenation演算子の行推定値はである必要があること~4.3 billion rows、またはその2つの入力の行推定値の合計であることは明らかです。 しかし、の推定値は~238 million rows、最適につながる、生成されるSort/ Stream AggregatetempdbのにデータのGB数百をこぼし戦略。この場合の論理的に一貫した推定は、を生成しHash Aggregate、流出を除去し、クエリパフォーマンスを劇的に改善します。 これはSQL Server 2014のバグですか?入力よりも低い見積もりが合理的である有効な状況はありますか?どのような回避策が利用可能ですか? ここで完全なクエリプラン(匿名化)が。出力QUERYTRACEON 2363または類似のトレースフラグを提供するためにこのサーバーにsysadminアクセスすることはできませんが、役立つ場合は管理者からこれらの出力を取得できる場合があります。 データベースは互換性レベル120にあるため、新しいSQL Server 2014 Cardinality Estimatorを使用しています。 統計は、データがロードされるたびに手動で更新されます。データ量を考えると、現在デフォルトのサンプリングレートを使用しています。より高いサンプリングレート(またはFULLSCAN)が影響を与える可能性があります。

3
この結合カーディナリティの推定値が非常に大きいのはなぜですか?
私は、次のクエリのカーディナリティの推定値が非常に高いと思うことを経験しています: SELECT dm.PRIMARY_ID FROM ( SELECT COALESCE(d1.JOIN_ID, d2.JOIN_ID, d3.JOIN_ID) PRIMARY_ID FROM X_DRIVING_TABLE dt LEFT OUTER JOIN X_DETAIL_1 d1 ON dt.ID = d1.ID LEFT OUTER JOIN X_DETAIL_LINK lnk ON d1.LINK_ID = lnk.LINK_ID LEFT OUTER JOIN X_DETAIL_2 d2 ON dt.ID = d2.ID LEFT OUTER JOIN X_DETAIL_3 d3 ON dt.ID = d3.ID ) …

1
クエリプラン「Cardinality Estimate」の警告
create table T(ID int identity primary key) insert into T default values insert into T default values go select cast(ID as varchar(10)) as ID from T where ID = 1 上記のクエリのクエリプランには警告があります。 <Warnings> <PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT(varchar(10),[xx].[dbo].[T].[ID],0)" /> </Warnings> なぜ警告があるのですか? フィールドリストのキャストは、カーディナリティの見積もりにどのように影響しますか?

1
SQL Server 2014 COUNT(DISTINCT x)は、列xの統計密度ベクトルを無視します
以下のためにCOUNT(DISTINCT)〜10億の異なる値を持っている、私は約3万行を持っていると推定ハッシュ集計でクエリプランを取得しています。 なんでこんなことが起こっているの?SQL Server 2012は適切な見積もりを生成しますが、これはSQL Server 2014のバグであり、Connectで報告する必要がありますか? クエリと貧弱な見積もり -- Actual rows: 1,011,719,166 -- SQL 2012 estimated rows: 1,079,130,000 (106% of actual) -- SQL 2014 estimated rows: 2,980,240 (0.29% of actual) SELECT COUNT(DISTINCT factCol5) FROM BigFactTable OPTION (RECOMPILE, QUERYTRACEON 9481) -- Include this line to use SQL 2012 CE -- Stats for …

1
流出をtempdbにソートしますが、推定行は実際の行と等しくなります
最大メモリを25GBに設定したSQL Server 2016 SP2では、1分間に約80回実行されるクエリがあります。クエリにより、約4000ページがtempdbに流出します。これにより、tempdbのディスクで大量のIOが発生します。 あなたが見てとるときにクエリプラン(簡体クエリを)あなたは、推定行数は実際の行数と同じであるが、依然として発生こぼれることがわかります。したがって、古い統計が問題の原因になることはありません。 私はいくつかのテストを行い、次のクエリをTempdbにスピルしました。 select id --uniqueidentifier from SortProblem where [status] ='A' order by SequenceNumber asc option (maxdop 1) しかし、別の列を選択した場合、流出は発生しません。 select startdate --datetime from SortProblem where [status] ='A' order by SequenceNumber asc option (maxdop 1) そこで、id列のサイズを「拡大」しようとしました。 select CONVERT(nvarchar(512),id) from SortProblem where [status] ='A' order by SequenceNumber asc option …

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がどのように評価するかを理解しようとしています。 インターネット上で、ステップ内統計値の基数推定で、私は同様の質問に出くわし、Paul Whiteはそれに対してかなり興味深い答えを出しました。 Paulの答えによれば、述語> =および>のカーディナリティーを推定するための式(この場合、少なくとも120のカーディナリティー推定モデルにのみ興味があります)は次のとおりです。 >の場合: Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1))) > =の場合: Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1)) TransactionDate列と '20140614'から '20140618'までの日時の範囲を使用して、範囲の述語に基づいてAdventureWorks2014データベースの[Production]。[TransactionHistory]テーブルでこれらの式の適用をテストしました。 この範囲のヒストグラムステップの統計は次のとおりです。 式に従って、次のクエリの基数を計算しました。 SELECT COUNT(1) FROM [AdventureWorks2014].[Production].[TransactionHistory] WHERE [TransactionDate] BETWEEN '20140615 00:00:00.000' AND '20140616 00:00:00.000' …

2
内部結合のカーディナリティ推定問題
行の推定が非常に間違っている理由を理解するのに苦労しています、ここに私の場合があります: 単純な結合-SQL Server 2016 sp2を使用(sp1と同じ問題)、dbcompatiblity = 130。 select Amount_TransactionCurrency_id, CurrencyShareds.id from CurrencyShareds INNER JOIN annexes ON Amount_TransactionCurrency_id = CurrencyShareds.Id option (QUERYTRACEON 3604, QUERYTRACEON 2363); SQLは1行を推定しますが、107131であり、ネストされたループを実行することを選択します(planへのリンク)。CurrencySharedsの統計が更新された後、見積もりは問題なく、マージ結合が選択されます(新しいプランへのリンク)。CurrencySharedsに1つのレコードが追加されるとすぐに、統計が「古く」なり、sqlが誤った推定に戻ります。 この単純なクエリについてはあまり心配しませんが、これは大きなクエリの一部に過ぎず、これはドミノの始まりです... 1つの行を100レコードテーブルに追加すると、このような損傷が発生するのはなぜですか?カーディナリティ推定トレースの出力を調べると、この警告***WARNING: badly-formed histogram ***が表示されますが、このトピックに関する詳細は見つかりませんでした。 ここに、カーディナリティ推定からの完全な出力が出力されます: Begin selectivity computation Input tree: LogOp_Join CStCollBaseTable(ID=1, CARD=107131 TBL: annexes) CStCollBaseTable(ID=2, CARD=100 TBL: CurrencyShareds) ScaOp_Comp x_cmpEq ScaOp_Identifier QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id …

1
SQL Server 2016のSUBSTRING()を含む述語の見積もりの​​変更?
SUBSTRING()または他の文字列関数を含む述語のカーディナリティを推定する方法に関するSQL Server 2016の変更に関するドキュメントまたは調査はありますか? 私が尋ねている理由は、互換モード130でパフォーマンスが低下したクエリを見て、SUBSTRING()の呼び出しを含むWHERE句に一致する行数の推定値の変更に関係した理由です。クエリの書き換えで問題を修正しましたが、SQL Server 2016のこの領域の変更に関するドキュメントを誰かが知っているかどうか疑問に思っています。 デモコードは次のとおりです。このテストケースでは推定値は非常に近いものですが、精度はデータによって異なります。 テストケースでは、compatレベル120ではSQL Serverは推定にヒストグラムを使用しているように見えますが、compatレベル130ではSQL Serverはテーブルの10%が固定されていると仮定しています。 CREATE DATABASE MyStringTestDB; GO USE MyStringTestDB; GO DROP TABLE IF EXISTS dbo.StringTest; CREATE TABLE dbo.StringTest ( [TheString] varchar(15) ); GO INSERT INTO dbo.StringTest VALUES ( 'Y5_CLV' ); INSERT INTO dbo.StringTest VALUES ( 'Y5_EG3' ); INSERT INTO dbo.StringTest VALUES ( 'ZY_NE' …

1
SQL Serverのオプティマイザーは、結合されたテーブルの行数をどのように推定しますか?
AdventureWorks2012データベースでこのクエリを実行しています。 SELECT s.SalesOrderID, d.CarrierTrackingNumber, d.ProductID, d.OrderQty FROM Sales.SalesOrderHeader s JOIN Sales.SalesOrderDetail d ON s.SalesOrderID = d.SalesOrderID WHERE s.CustomerID = 11077 推定実行計画を見ると、次のことがわかります。 最初のインデックスシーク(右上)はIX_SalesOrderHeader_CustomerIDインデックスを使用し、リテラル11077で検索しています。推定推定値は2.6192行です。 を使用するDBCC SHOW_STATISTICS ('Sales.SalesOrderHeader', 'IX_SalesOrderHeader_CustomerID') WITH HISTOGRAMと、値11077が2つのサンプリングされたキー11019と11091の間にあることがわかります。 11019から11091までの個別の行の平均数は2.619718であり、2.61972に丸められます。これは、インデックスシークで表示される推定行の値です。 私が理解していない部分は、SalesOrderDetailテーブルに対するクラスター化インデックスシークの推定行数です。 私が実行した場合DBCC SHOW_STATISTICS ('Sales.SalesOrderDetail', 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID'): したがって、SalesOrderID(私が参加している)の密度は3.178134E-05です。これは、1 / 3.178134E-05(31465)がSalesOrderDetailテーブルの一意のSalesOrderID値の数に等しいことを意味します。 SalesOrderDetailに31465個の一意のSalesOrderIDがあり、均等に分布している場合、SalesOrderIDあたりの平均行数は121317(行の総数)を31465で割った値です。平均は3.85561です。 したがって、ループスルーの推定行数が2.61972で、平均が3.85561で返される場合、推定行数は2.61972 * 3.85561 = 10.10062になると思います。 ただし、推定行数は11.4867です。 2番目の推定値の私の理解は間違っていると思います。異なる数字はそれを示しているようです。私は何が欠けていますか?

3
並列処理(パーティションストリーム)演算子が行の推定値を1に減らすのはなぜですか?
SQL Server 2012 Enterpriseを使用しています。私は完全に直感的ではないいくつかの動作を示しているSQLプランに出会いました。大量のパラレルインデックススキャン操作の後、パラレル化(パーティションストリーム)操作が発生しますが、インデックススキャン(Object10.Index2)によって返される行の推定値を強制終了し、推定値を1に減らします。この振る舞いを説明するものに出会ったことはありません。クエリは非常に単純ですが、各テーブルには数百万のレコードが含まれています。これはDWHロードプロセスの一部であり、この中間データセットは何度も触れられますが、私が抱えている問題は、特に行の見積もりに関連しています。正確な行の推定値が並列処理(パーティション分割)演算子内で1になる理由を説明できますか?また、 計画を貼り付けるために完全な計画を投稿しました。 問題の操作は次のとおりです。 コンテキストを追加する場合に備えてプランツリーを含める: Paul Whiteが提出したこのConnectアイテムのバリエーションにぶつかることはありますか(彼のブログでさらに詳しく説明しています)。少なくとも、私が見つけた唯一のものは、プレイ中のTOP演算子がなくても、私が実行しているものに少しでも近いようです。

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