1

要件は、テーブル「empl」の 65 列すべてを最小 IOでページングに 50 レコードをロードすることです。テーブルには 280000 件以上のレコードがあります。PK 上のクラスター化インデックスは 1 つだけです。

ページネーションクエリは次のとおりです。

WITH result_set AS (    
SELECT    
ROW_NUMBER() OVER (ORDER BY  e.[uon] DESC ) AS [row_number], e.*    
FROM    
empl e with (NOLOCK)    
LEFT JOIN empl_add ea with (NOLOCK)    
ON ea.ptid = e.ptid    
WHERE    
e.del = 0 AND e.pub = 1 AND e.sid = 2
AND e.md = 0     
AND e.tid = 3    
AND e.coid = 2     
AND (e.cid = 102)
AND ea.ptgid IN (SELECT ptgid FROM empl_dep where psid = 1001
AND ib = 1)) 
SELECT  
*  
FROM  
result_set  
WHERE  
[row_number] BETWEEN 0 AND 50

以下は、プロファイラーから上記のクエリを実行した後の統計です。

CPU: 1500、読み取り: 25576、期間: 25704

次に、テーブル empl に次のインデックスを配置します。

CREATE NONCLUSTERED INDEX [ci_empl]
ON [dbo].[empl] ([del],[md],[pub],[tid],[coid],[sid],[ptid],[cid],[uon])
GO

インデックスを配置した後、CPU と読み取りはさらに高くなります。インデックスのどこが悪いのか、クエリのどこが悪いのかわかりませんか?

編集:

次のクエリも、インデックスを配置した後に高い読み取りを行っています。そして、3 つの列と 1 つのカウントしかありません。

SELECT TOP (2147483647)
ame.aid ID, ame.name name,         
COUNT(empl.pid) [Count], ps.uff uff FROM ame with (NOLOCK)        
JOIN pam AS pa WITH (NOLOCK) ON pa.aid = ame.aid         
JOIN empl WITH (NOLOCK) ON empl.pid = pa.pid         
LEFT JOIN psam AS ps
ON ps.psid = 1001
AND ps.aid = ame.aid
LEFT JOIN empl_add ea with (NOLOCK)        
ON ea.ptid = empl.ptid        
WHERE 
empl.del = 0 AND empl.pub = 1 AND empl.sid = 2
AND empl.md = 0         
AND (empl.tid = 3)        
AND (empl.coid = 2)        
AND (empl.cid = 102)        
AND ea.ptgid IN (SELECT ptgid FROM empl_dep where psid = 1001
AND ib = 1)        
AND ame.pub = 1 AND ame.del = 0        
GROUP BY ame.aid, ame.name, ps.uff        
ORDER BY ame.name ASC

2番目の編集:

これで、「uon」列に次のインデックスを配置しました。

CREATE NONCLUSTERED INDEX [ci_empl_uon]
ON [dbo].[empl] (uon)
GO

しかし、それでも CPU と読み取りは高くなっています。

3 番目の編集:

DTA は、最初のクエリにすべての列を含むインデックスを提案しているので、提案されたインデックスを変更して、基本的な 4 つのフィルターのフィルター インデックスに変換し、より効果的にしました。

インデックスの作成中にインクルードの後に​​以下の行を追加しました。

Where e.del = 0 AND e.pub = 1 AND e.sid = 2 AND e.md = 0 AND e.coid = 2

それでも、開発マシンと本番マシンの両方で読み取りが高くなっています。

4番目の編集:

今、私はパフォーマンスを改善するソリューションにたどり着きましたが、それでも目標には達していません. 重要なのは、それがALL THE DATAではないということです。

クエリは次のとおりです。

WITH result_set AS (    
SELECT    
ROW_NUMBER() OVER (ORDER BY  e.[uon] DESC ) AS [row_number], e.pID pID   
FROM    
empl e with (NOLOCK)    
LEFT JOIN empl_add ea with (NOLOCK)    
ON ea.ptid = e.ptid    
WHERE    
e.del = 0 AND e.pub = 1 AND e.sid = 2
AND e.md = 0     
AND e.tid = 3    
AND e.coid = 2     
AND (e.cid = 102)
AND ea.ptgid IN (SELECT ptgid FROM empl_dep where psid = 1001
AND ib = 1)) 
SELECT  
*  
FROM  
result_set join empl on result_set.pID = empl.pID
WHERE  
[row_number] BETWEEN @start AND @end

キー列を変更してインデックスを再作成し、インクルードとフィルター処理を行います。

CREATE NONCLUSTERED INDEX [ci_empl]
ON [dbo].[empl] ([ptid],[cid],[tid],[uon])
INCLUDE ([pID])
Where 
[coID] = 2 and
[sID] = 2 and
[pub] = 1 and
[del] = 0 and
[md] = 0
GO

パフォーマンスは向上しますが、目標には達しません。

4

2 に答える 2