2

jobs テーブルには 100 万件のレコードがあります。次のクエリの実行時間は 30 秒です。クエリは洗練されておらず、条件に一致するレコードの数を返します。最適化を手伝ってください。

DECLARE @MaxIdValue varchar(100)
DECLARE @SerchFilter varchar(100) = 'test'
DECLARE @TotalRowCount int = ( SELECT 
Count(*) AS [RowCount]
FROM 
[Jobs]
INNER JOIN [Sites] ON [Jobs].[SiteId] = [Sites].[Id]  
INNER JOIN [JobStatusHistory] ON [Jobs].[JobStatusHistoryId] = [JobStatusHistory].[Id]  
INNER JOIN [JobStatuses] ON [JobStatusHistory].[StatusId] = [JobStatuses].[Id]  
INNER JOIN [JobTypes] ON [Jobs].[JobTypeId] = [JobTypes].[Id]  
LEFT JOIN [Customers] ON [Jobs].[CustomerId] = [Customers].[Id]  
LEFT JOIN [Priorities] ON [Jobs].[PriorityId] = [Priorities].[Id]  
LEFT JOIN [TaskTypes] ON [Jobs].[TaskTypeId] = [TaskTypes].[Id]  
LEFT JOIN [Areas] ON [Sites].[AreaId] = [Areas].[Id]  
WHERE
( 
 [Sites].[Active]=1
 AND 
   (
    [Jobs].[OwnedByCompanyId]=18
      OR  
    [Jobs].[OwnedByCompanyId] = 0)
      AND 
    [Jobs].[Active]=1
   ) 
 AND 
   ( 
  [Customers].[Name] LIKE '%'+@SerchFilter+'%'
 OR 
   [Sites].[Name] LIKE  '%'+@SerchFilter+'%'
   OR 
 [Sites].[Address1] LIKE  '%'+@SerchFilter+'%'
    OR 
  [Sites].[Postcode] LIKE  '%'+@SerchFilter+'%'
 OR 
  [Sites].[UPRN] LIKE  '%'+@SerchFilter+'%'
 OR 
 [Sites].[Contact] LIKE  '%'+@SerchFilter+'%'
     OR 
 [Sites].[Telephone] LIKE  '%'+@SerchFilter+'%'
   OR 
 [Sites].[Work] LIKE  '%'+@SerchFilter+'%'
 OR 
  [Sites].[MobileNumber] LIKE  '%'+@SerchFilter+'%'
  OR 
  [Areas].[Description] LIKE  '%'+@SerchFilter+'%'
    OR 
   [Jobs].[Id] LIKE  '%'+@SerchFilter+'%'
  OR 
  [Jobs].[OrderNumber] LIKE  '%'+@SerchFilter+'%'
   OR 
   [Jobs].[Description_PlainText] LIKE  '%'+@SerchFilter+'%'
  OR 
   [Jobs].[JobNumber] LIKE  '%'+@SerchFilter+'%'
  OR 
  [JobTypes].[Description] LIKE  '%'+@SerchFilter+'%'
   OR 
  [TaskTypes].[Description] LIKE  '%'+@SerchFilter+'%'
     OR 
   [Priorities].[Description] LIKE  '%'+@SerchFilter+'%'
    ) 
  )
4

3 に答える 3

1

'%'+@SerchFilter+'%'最適化は、をに置き換えること@SerchFilter+'%'です。

where句'%'+@SerchFilter+'%'は、インデックスシークの使用を防ぎます。

編集:

これらすべてのフィールドを一度にフィルタリングする必要が本当にありますか?それが数ではない場合、なぜTelephoneフィールドでインセンスを探すのが面倒なのか。

SQL Server 2005以降を使用している場合は、FullText-Searchの使用を検討してください。

于 2012-08-15T11:40:15.953 に答える
1

結合列が適切にインデックス化されていると仮定すると、問題は多数の LIKE にあると思われます。残念ながら、これらは非常に高価な DB 操作です。

同様のことを行った後、次のようなことを行うことで、パフォーマンスがわずかに向上する可能性があると思います。

SELECT COUNT(*) FROM ... WHERE COL1 + COL2 + COL3 + COL4 + COL5 LIKE '%SEARCH%'

それよりも:

SELECT COUNT(*) FROM ... WHERE 
COL1 LIKE '%SEARCH%' 
OR COL2 LIKE '%SEARCH%'
OR COL3 LIKE '%SEARCH%'
OR COL4 LIKE '%SEARCH%'
OR COL5 LIKE '%SEARCH%'
于 2012-08-15T12:14:50.323 に答える
1

より多くの索引と全文カタログを使用することをお勧めします。

MS SQL 2008 を使用している場合は、実行計画で不足しているインデックスを確認できます。また、ここから、なぜそんなに時間がかかるのかがわかります。

于 2012-08-15T11:54:20.877 に答える