web-dev-qa-db-ja.com

SELECT TOP 1はクエリのパフォーマンスを低下させます。これを克服するdbaアクセス可能な方法はありますか?

運用アプリケーション(C#がSQL Server 2014 Standardと通信)には、以下のようなクエリがあります。ほとんどの場合、ミリ秒単位で実行されます。しかし、ときどき(@Idの特定の値の場合)、異常になり、1分ほどかかります。これはアプリのタイムアウトよりも長いため、ユーザーにとってアプリは失敗します。

「ゴーズナッツ」の場合、他のすべてのケースではなく多くのケースで返される結果セットは正しく空です。

幸いなことに、これは本番環境と開発環境の両方で再現可能です。

開発者は、クエリから "TOP 1"を削除し、アプリが結果セットの余分な行を消費することを確認すると、パフォーマンスの問題が解消されると述べています。

TOP 1が存在する場合、クエリプランナーはインデックスを提案しません。 (開発中)。

クエリの変更とアプリの修正が進行中です。ロールアウトにはしばらく時間がかかります。

私の質問:新しいクエリを使用したアプリの変更がロールアウトされる前に、この問題を克服するためにDBAがアクセスできる運用SQL Serverインスタンスを調整または調整する方法はありますか?

SELECT TOP 1
       subscription_id 
  FROM subscription AS sub
  JOIN billing_info AS bi ON bi.billing_info_id = sub.billing_info_id   
  JOIN person_group AS apg ON apg.person_id = bi.person_id
  JOIN pplan ON pplan.plan_id = sub.plan_id
  JOIN product ON product.product_id = [plan].product_id 
  JOIN product_attribute ON product_attribute.product_id = product.product_id 
 WHERE apg.group_id = @Id
   AND apg.start_date < GETDATE()
   AND (apg.end_date IS NULL OR apg.end_date > GETDATE()) 
   AND (sub.end_date IS NULL OR sub.end_date > GETDATE()) 
   AND product_attribute.attribute_type = 'special feature' 
   AND product_attribute.attribute_data = '1' 
 ORDER BY sub.start_date ASC;
13
O. Jones

クエリを変更できない場合は、プランガイドを使用できます。

OPTION (QUERYTRACEON 4138) を使用してクエリのパフォーマンスをテストします(これを試すには、sysadmin権限を持つユーザーが必要です)。

それで十分なパフォーマンスが得られる場合は、計画ガイドを使用してこれを適用できます。満足のいくパフォーマンスが得られない場合は、そのヒントを見つけてください。おそらくOPTION (HASH JOIN, MERGE JOIN)不適切なネストされたループが問題の場合。 USE PLAN N'...'ヒントに頼る必要があるかもしれません。

必要なヒントがわかったら、情報 here を使用して適用できます。

12
Martin Smith

にっこりしてみてください
`>は> =に変更されているため、まったく同じクエリではありません

SELECT TOP 1
       subscription_id 
  FROM subscription AS sub
  JOIN billing_info AS bi 
        ON bi.billing_info_id = sub.billing_info_id   
  JOIN person_group AS apg 
        ON apg.person_id = bi.person_id 
       AND apg.group_id = @Id
       AND apg.start_date < GETDATE()
       AND isnnull(apg.end_date, GETDATE()) >= GETDATE()             
  JOIN pplan 
        ON pplan.plan_id = sub.plan_id
       AND isnnull(sub.end_date, GETDATE()) >= GETDATE()
  JOIN product 
        ON product.product_id = [plan].product_id 
  JOIN product_attribute 
        ON product_attribute.product_id = product.product_id 
       AND product_attribute.attribute_type = 'special feature' 
       AND product_attribute.attribute_data = '1' 
 ORDER BY sub.start_date ASC;
0
paparazzo