私はSQLでかなり新しいですが、私はより速く継承した既存のクエリをいかにして作り出すかを考えなければなりません。ここで一時テーブルを使用した高速SQLクエリですか?
は、そこにそれらのいずれかのWHERE句です:
@SearchFor nvarchar(200)
,@SearchIn nvarchar(1024)
,@SearchActivity int
-- stuff here I've left out ---
WHERE
(-- filter for all queries --
(FT_TBL.IsActive = 1)
AND (FT_TBL.IsPro = 1)
AND (
(FT_TBL.DatePaidUpTo >= @CurrentTime)
OR (
(FT_TBL.IsFromPaidBusinessDB = 1)
AND (FT_TBL.DatePaidUpTo IS NULL)
)
)
AND (aspnet_Membership.IsApproved = 1)
)
AND (-- filter if user fills in 'searchfor' box --
(@SearchFor IS NULL)
OR (FT_TBL.CompanyName like '%' + @SearchFor + '%')
OR (aspnet_Users.UserName like '%' + @SearchFor + '%')
OR (Activities.Activity like '%' + @SearchFor + '%')
)
AND (-- filter if user fills in 'searchIn' box --
(@SearchIn IS NULL)
OR (a1.City LIKE '%' + @SearchIn + '%')
OR (a1.Region LIKE '%' + @SearchIn + '%')
OR (a1.Postcode LIKE '%' + @SearchIn + '%')
OR (Country.Name LIKE '%' + @SearchIn + '%')
)
AND (-- filter by activity --
(@SearchActivity IS NULL)
OR (@SearchActivity = Activities.ActivityID)
)
AND NOT EXISTS (Select a2.AddressId, a2.UserId
from Addresses a2
where a2.userid = a1.UserId
and a2.addressid < a1.addressid
)
SearchIn
、SearchFor
、およびSearchActivity
それは、検索結果をフィルタリングするために通過できるという三つのフィールドです。考え方は、これらのそれぞれについて 'null'が渡された場合、検索結果の唯一の制約はWHERE句の最初のブロックに由来するということです。これらの3つのフィールドのいずれかがNULLでない場合、結果はその行のロケーション、名前、またはカテゴリに基づいてさらに制約されます。最後のブロックは少しトリックです。ユーザーはいくつかのアドレスを付けることができますが、各ユーザーには1つの行しか返されません。したがって、このブロックはIDが最も小さいアドレスを選択します。
このクエリは非常にゆっくり実行されます。私たちのハードウェアがアンダーパールであることもありますが、このプロシージャは十分効率的ではないためです。私は、SQLをどのように同時に動作させるのかを学ぶ際に、難しい問題を解決する方法を試しています。
私が持っていたアイデアの1つは、2段階で検索を実行することでした。たとえば、最初にWHERE
句の最初のブロックのみを使用してクエリを実行し、次に結果テーブルに2番目のクエリを実行します。残りのブロックはWHERE
節にあります。最初のブロックがテーブル内の多くの行を除外するので、これが役立つと思いました。
誰かがこのクエリを改善する良い方法を提案できますか?また、どのツールがクエリの効率をテストするのに最適ですか?同じ入力であっても実行時間が大きく変動することがあります。
参考までに、あなたの 'LIKE'比較のどれもインデックスを使うことができないので、私はそれだけで**テーブルスキャン**を最小にしています** – JNK
私はそれをやることができません他の方法 - ユーザーのテキスト入力に基づく検索。 – Oliver
フルテキストインデックスを調べる – JNK