簡體   English   中英

SQL 查詢花費太多時間在生產環境中執行

[英]SQL Query taking too much time to execute on production

SQL 查詢執行時間過長。 在 UAT 工作得很好。 我需要比較兩個表的數據並想得到差異。 下面提到的是我的查詢。

Select *
from tblBrandDetailUsers tbdu 
inner join tblBrands tbs on tbs.BrandId = tbdu.BrandId
left join tblBrandDetails tbd on tbd.CategoryId = tbdu.CategoryId
    and tbd.BrandId = tbdu.BrandId
    and tbd.CityId = tbdu.CityId
inner join tblCategory tc on tbdu.CategoryId = tc.CategoryId
inner join tblCity tcc on tcc.CityId = tbdu.CityId  
where isnull(tbdu.SaleAmount,-1) <> isnull(tbd.SaleAmount,-1)
and isnull(tbdu.CityId,0) =  3
and isnull(tbdu.TopLevelCategoryId,0) = 2;

需要優化查詢。

您需要檢查的一些事項:

  1. 每個表的行數。 你擁有的行越多,速度就越慢。 你有與 UAT 相同大小的數據嗎?
  2. SELECT * :避免使用*並且只檢索您需要的列。
  3. WHERE謂詞左側的ISNULL function 將掃描索引,因為它是non-sargable 您可以在此處查看答案並在WHERE子句左側不帶任何 function 的情況下重寫謂詞。

您需要提供詳細信息,例如實際執行計划。 我只能給你一個籠統的答案,因為沒有提供太多細節。

請記住 UAT 在 PROD 中非常不同。 您使用的硬件,行數等。

評論中的每個建議看起來都是正確的。 UAT和Prod的區別應該是數據量。 您的問題應該是缺乏索引或索引效率低下。 你應該添加復合索引

tblBrandDetails.CategoryId,tblBrandDetails.BrandId, tblBrandDetails.CityId

等等

tblBrandDetailUsers.CategoryId,tblBrandDetailUsers.BrandId, tblBrandDetailUsers.CityId

確保所有唯一 ID 都有一個 btree 索引(或類似類型的索引,具體取決於您的數據庫)

您還可以添加條件索引以更快地過濾 null 值: https://www.brentozar.com/archive/2015/09/filtered-indexes-and-is-not-null/

像這樣重寫您的查詢:

Select *--> AVOID "*" put all the necessary columns
from   tblBrandDetailUsers AS tbdu 
       inner join tblBrands AS tbs on tbs.BrandId = tbdu.BrandId
       left join tblBrandDetails AS tbd on tbd.CategoryId = tbdu.CategoryId
                                     and tbd.BrandId = tbdu.BrandId
                                     and tbd.CityId = tbdu.CityId
       inner join tblCategory AS tc on tbdu.CategoryId = tc.CategoryId
       inner join tblCity AS tcc on tcc.CityId = tbdu.CityId  
where  tbdu.SaleAmount <> tbd.SaleAmount
  and  tbdu.CityId =  3
  and  tbdu.TopLevelCategoryId = 2
UNION ALL
SELECT * --> AVOID "*" put all the necessary columns
from   tblBrandDetailUsers AS tbdu 
       inner join tblBrands AS tbs on tbs.BrandId = tbdu.BrandId
       left join tblBrandDetails AS tbd on tbd.CategoryId = tbdu.CategoryId
                                     and tbd.BrandId = tbdu.BrandId
                                     and tbd.CityId = tbdu.CityId
       inner join tblCategory AS tc on tbdu.CategoryId = tc.CategoryId
       inner join tblCity AS tcc on tcc.CityId = tbdu.CityId  
where  tbdu.SaleAmount IS NULL
  AND  tbd.SaleAmount IS NULL
  and  tbdu.CityId =  3
  and  tbdu.TopLevelCategoryId = 2;

修改 SELECT 子句使其只有必要的列而不是 *

確保您的索引接近於:

對於 tblBrandDetailUsers 表:

  1. index KEY (CityId, TopLevelCategoryId, BrandId, CategoryId) INCLUDE (SaleAmount)

  2. index KEY (CityId, TopLevelCategoryId, CategoryId) INCLUDE (SaleAmount)

對於 tblBrandDetails 表:

  1. 索引(CityId、BrandId、CategoryId)

並且:

  1. tblCategory(類別 ID)

  2. tblCity (CityId)

  3. tblBrands(品牌標識)

當您糾正查詢尤其是 SELECT 子句時,我們可以為您提供更准確的索引,因為選擇的列對索引性能有很大的影響!

正如其他人所建議的那樣,嘗試在用於連接的列上添加索引

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM