14

私はパフォーマンス上の理由から少し前に dapper.net を使い始めました。名前付きパラメーター機能は、LINQ To SQL で "ExecuteQuery" を実行するよりも気に入っています。

ほとんどのクエリでうまく機能しますが、時々本当に奇妙なタイムアウトが発生します。最も奇妙なことは、このタイムアウトは、SQL が dapper を介して実行された場合にのみ発生することです。プロファイラーからコピーされた実行済みのクエリを取り、Management Studio で実行するだけで、高速で完璧に動作します。そして、それは一時的な問題だけではありません。クエリは常に dapper を介してタイムアウトし、Management Studio で一貫して正常に動作します。

exec sp_executesql N'SELECT Item.Name,dbo.PlatformTextAndUrlName(Item.ItemId) As PlatformString,dbo.MetaString(Item.ItemId) As MetaTagString, Item.StartPageRank,Item.ItemRecentViewCount
                    NAME_SRCH.RANK as NameRank,
                    DESC_SRCH.RANK As DescRank, 
                    ALIAS_SRCH.RANK as AliasRank, 
                    Item.itemrecentviewcount,
                    (COALESCE(ALIAS_SRCH.RANK, 0)) + (COALESCE(NAME_SRCH.RANK, 0)) + (COALESCE(DESC_SRCH.RANK, 0) / 20) + Item.itemrecentviewcount / 4 + ((CASE WHEN altrank > 60 THEN 60 ELSE altrank END) * 4) As SuperRank
                    FROM dbo.Item
                    INNER JOIN dbo.License on Item.LicenseId = License.LicenseId

                    LEFT JOIN dbo.Icon on Item.ItemId = Icon.ItemId
                    LEFT OUTER JOIN FREETEXTTABLE(dbo.Item, name, @SearchString) NAME_SRCH ON
                    Item.ItemId = NAME_SRCH.[KEY] 
                    LEFT OUTER JOIN FREETEXTTABLE(dbo.Item, namealiases, @SearchString) ALIAS_SRCH ON
                    Item.ItemId = ALIAS_SRCH.[KEY] 
                    INNER JOIN FREETEXTTABLE(dbo.Item, *, @SearchString) DESC_SRCH ON
                    Item.ItemId = DESC_SRCH.[KEY]
                    ORDER BY SuperRank DESC OFFSET @Skip ROWS FETCH NEXT @Count ROWS ONLY',N'@Count int,@SearchString nvarchar(4000),@Skip int',@Count=12,@SearchString=N'box,com',@Skip=0

これは、SQL プロファイラーからコピーして貼り付けたクエリです。私は自分のコードでこのように実行します。

            using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Conn"].ToString())) {
            connection.Open();
            var items = connection.Query<MainItemForList>(query, new { SearchString = searchString, PlatformId = platformId, _LicenseFilter = licenseFilter, Skip = skip, Count = count }, buffered: false);
            return items.ToList();
        }

ここからどこから始めればよいかわかりません。コードを実行するだけでうまく動作するので、dapperで何かが起こっているに違いないと思います。

このスクリーンショットでわかるように。これは、最初にコードを介して実行され、次に Management Studio を介して実行されるクエリと同じです。

ここに画像の説明を入力

また、これは、2 つ以上の単語がある場合、または検索文字列に「停止」文字がある場合にのみ発生すると思います (と思います)。そのため、全文検索に何か問題がある可能性がありますが、Management Studio から完全に機能するため、デバッグ方法がわかりません。

さらに悪いことに、私のローカルホストでは、コードと Management Studio の両方からほぼ同じデータベースを使用して正常に動作します。

4

4 に答える 4

13

Dapper は、ado.net のユーティリティ ラッパーにすぎません。ado.net の動作に変更はありません。ここでの問題は、「ssms で動作し、ado.net で失敗する」ことだと私には思えます。これは珍しいことではありません。時折これを見つけるのはかなり一般的です。有力候補:

  • 「set」オプション: これらは ado.net で異なるデフォルトを持ちます - 特に計算列 + 永続化 + インデックス付き列などがある場合、パフォーマンスに影響を与える可能性があります - 「set」オプションに互換性がない場合、格納された値であるため、インデックスではなく、代わりにテーブルスキャンして再計算します。他にも同様のシナリオがあります。
  • システム負荷 / トランザクション分離レベル / ブロッキング。ssms で何かを実行しても、その時点でのシステム負荷全体が再現されない
  • キャッシュされたクエリ プラン: ダフ プランがキャッシュされて使用されることがあります。ssms から実行すると、通常、新しい計画が強制されます。これは、テストで使用しているパラメーターに合わせて自然に調整されます。すべてのインデックス統計などを更新し、「最適化」クエリ ヒントを追加することを検討してください
于 2013-03-29T09:42:04.170 に答える
2

Dapper でコマンドのタイムアウトを設定することが問題になる可能性があります。Dapper でコマンド タイムアウトを調整する方法の例を次に示します。 Dapper でコマンド タイムアウトを 設定する

于 2013-03-28T13:41:06.623 に答える