2012-04-18 5 views
3

SQLクエリがあり、レポートのデータを取得するために使用されています。それは機能します、ちょうどそれがプログラムを報告書を引っ張るのに長時間かかります。このSQLを最適化する方法はありますか? SYSPROD1という名前のリンクサーバーを使用して、複数のサブクエリを持つSELECTクエリです。私は試しましたが、成功しませんでした。リンクされたサーバーでのSQLクエリの最適化

Select 
     invMaster.StockCode, prodclass.[Description], invMaster.LongDesc, 
     (select inv.QtyOnHand from SYSPROD1.SysproCompanyD.dbo.InvWarehouse inv where inv.StockCode = invMaster.StockCode and inv.Warehouse = 'P4') as CSSJHB, 
     (select inv.QtyOnHand from SYSPROD1.SysproCompanyD.dbo.InvWarehouse inv where inv.StockCode = invMaster.StockCode and inv.Warehouse = 'KK') as KFCJHB, 
     (select inv.QtyOnHand from SYSPROD1.SysproCompanyD.dbo.InvWarehouse inv where inv.StockCode = invMaster.StockCode and inv.Warehouse = 'KF') as KFCMIDRAND, 
     (select inv.QtyOnHand from SYSPROD1.SysproCompanyD.dbo.InvWarehouse inv where inv.StockCode = invMaster.StockCode and inv.Warehouse = 'QK') as QKJHB, 
     (select inv.QtyOnHand from SYSPROD1.SysproCompanyD.dbo.InvWarehouse inv where inv.StockCode = invMaster.StockCode and inv.Warehouse = 'SD') as SDBBLOEM, 
     (select inv.QtyOnHand from SYSPROD1.SysproCompanyD.dbo.InvWarehouse inv where inv.StockCode = invMaster.StockCode and inv.Warehouse = 'SL') as SEQUENCE, 
     (select inv.QtyOnHand from SYSPROD1.SysproCompanyD.dbo.InvWarehouse inv where inv.StockCode = invMaster.StockCode and inv.Warehouse = 'PA') as CSSCT, 
     (select inv.QtyOnHand from SYSPROD1.SysproCompanyD.dbo.InvWarehouse inv where inv.StockCode = invMaster.StockCode and inv.Warehouse = 'VL') as CSGEORGE 



from   
     SYSPROD1.SysproCompanyD.dbo.InvMaster invMaster join SYSPROD1.SysproCompanyD.dbo.SalProductClass prodclass 
     on invMaster.ProductClass = prodclass.ProductClass 

    where prodclass.[Description] in ('WHOLEBIRDS','ABI & OTHER', 'CATERING PORTIONS', 'FILLETED PRODUCTS', 'FRESH PRODUCTS','INDUSTRIAL CATERING', 'IQF PORTIONS', 'LOW VALUE FIXED MASS', 'RED MEAT', 'REJECT EGGS' ,'SUNDRY PRODUCTS','VALUE ADDED')     
    group by invMaster.StockCode, prodclass.[Description], invMaster.LongDesc 

    order by prodclass.[Description], invMaster.StockCode asc 

答えて

3

ここで書いているソートのリンクされたサーバークエリ(リモートサーバー上の複数のテーブルが結合されている)は、SQLクエリエンジンがローカルクエリの計画を最適化するために使用する多くのトリックを使用できないため;たとえば、リンクされたサーバーへの接続に使用されるセキュリティコンテキストがsysadmin,db_ownerまたは​​ロールのメンバーである場合を除き、the calling server has no access to the table statisticsです。 このクエリの計画は、クエリの実行中にSYSPROD1.SysproCompanyD.dbo.InvMaster,SYSPROD1.SysproCompanyD.dbo.SalProductClassおよびSYSPROD1.SysproCompanyD.dbo.InvWarehouseの内容全体を呼び出し元のマシンに複数回プルする可能性があります。これは時間がかかることです。

このクエリのパフォーマンスを向上させるには、いくつかのオプションがあります。 1つは、クエリで結合する前に、リンクされたサーバーの各テーブルから必要な行を一時テーブルまたはテーブル変数に挿入することです。

第2に、この全体のクエリがリンクされたサーバー上のテーブルによって満たされている場合、そのサーバー上のビューとして作成することです - これはすべての処理がそこで実行され、効率的。

+0

リンクサーバー上のビューを作成し、それを素晴らしいと呼んでくれてありがとうございました。それは、それがイニシャル全体の約1/10になりました。 – Scott

+0

私のローカルサーバー上の一時テーブルは完全に私のために働いた。非常に迅速に実行されたtempテーブルに必要な行のSELECT INTOを実行した後、一時テーブルを使用してローカルテーブルに結合しました。良いヒント! –

0

あなたがJOIN秒でそれを最適化することができます:ここに私のSQLだ

Select  
     invMaster.StockCode, prodclass.[Description], invMaster.LongDesc, w1.QtyOnHand AS CSSJHB 

..<snip>

from   
     SYSPROD1.SysproCompanyD.dbo.InvMaster invMaster 
join SYSPROD1.SysproCompanyD.dbo.SalProductClass prodclass 
     on invMaster.ProductClass = prodclass.ProductClass 
INNER JOIN SYSPROD1.SysproCompanyD.dbo.InvWarehouse w1 on w1.StockCode = invMaster.StockCode AND w1.Warehouse = 'P4' 

などSELECTであなたのサブクエリごとに繰り返します。

+0

ありがとう、これは少しうまくいったが、私のクエリはまだ長時間走っていた。 – Scott