由于产品表中有大量记录,搜索查询会降低性能,请在sql server中提供良好的查询以优化给定的查询

时间:2010-06-25 09:10:12

标签: sql-server

SELECT  distinct tb_Ecomm_Product.SKU as ImageName,
        tb_Ecomm_Product.MainCategory,
        tb_Ecomm_Product.SEName,
        tb_Ecomm_Product.SKU,
        tb_Ecomm_Product.ProductID, 
        tb_Ecomm_Product.Name AS PName,
        (Case When (SalePrice Is Not Null And SalePrice!=0) Then 
            SalePrice 
        Else 
            Price 
        End) As SalePrice,
        (
            (20 * dbo.WordCount('HWD AquaBug', tb_Ecomm_Product.Name)) +
            (20 * dbo.WordCount('AquaBug HWD', tb_Ecomm_Product.Name)) +
            (20 * dbo.WordCount('', tb_Ecomm_Product.Name)) +
            (20 * dbo.WordCount('', tb_Ecomm_Product.Name)) +
            (20 * dbo.WordCount('', tb_Ecomm_Product.Name)) +
            (20 * dbo.WordCount('', tb_Ecomm_Product.Name)) +
            (12 * dbo.WordCount('HWD', tb_Ecomm_Product.Name)) +
            (12 * dbo.wordcount('',tb_Ecomm_Product.SKU)) +
            (12 * dbo.WordCount('AquaBug', tb_Ecomm_Product.Name)) +
            (12 * dbo.wordcount('',tb_Ecomm_Product.SKU)) +
            (12 * dbo.WordCount('', tb_Ecomm_Product.Name)) +
            (12 * dbo.wordcount('',tb_Ecomm_Product.SKU)) +
            (12 * dbo.WordCount('', tb_Ecomm_Product.Name)) +
            (12 * dbo.wordcount('',tb_Ecomm_Product.SKU)) +
            (12 * dbo.WordCount('', tb_Ecomm_Product.Name)) +
            (13 * dbo.wordcount('',tb_Ecomm_Product.SKU))  )  as rank 
FROM tb_Ecomm_Product 
Left join tb_Ecomm_Manufacture 
    on tb_Ecomm_Manufacture.ManufactureID = tb_Ecomm_Product.ManufactureID 
INNER JOIN tb_Ecomm_ProductCategory 
    ON tb_Ecomm_Product.ProductID = tb_Ecomm_ProductCategory.ProductID 
INNER JOIN tb_Ecomm_Category 
    ON tb_Ecomm_ProductCategory.CategoryID = tb_Ecomm_Category.CategoryID
Where tb_Ecomm_Product.StoreID = 1 
    And tb_Ecomm_Category.StoreID = 1 
    And Price != 0 
    And 
    (
        (Case When (SalePrice Is Not Null And SalePrice != 0) Then 
            SalePrice
         Else Price End) != 0 
    Or 
        (Case When (SalePrice Is Not Null And SalePrice != 0) Then 
            SalePrice 
         Else Price End) != null 
    ) 
    And tb_Ecomm_Product.Status = 1
    And tb_Ecomm_Product.Deleted = 0 
    And tb_Ecomm_Category.Status=1
    And tb_Ecomm_Category.Deleted = 0  
    and 
    (
        (tb_Ecomm_Product.name like '%HWD%' 
         or tb_Ecomm_Product.Description like '%HWD%' )  
    or 
        (tb_Ecomm_Product.name like '%AquaBug%' 
         or tb_Ecomm_Product.Description like '%AquaBug%' )  
    ) 
Order by rank desc

1 个答案:

答案 0 :(得分:2)

删除tb_Ecomm_Manufacture的联接,它不会在查询中的任何位置使用。

看起来您正在使用distinct,因为您已经通过tb_Ecomm_Category加入了tb_Ecomm_ProductCategory以进行一些过滤,但它会产生在结果集中乘以行的副作用。执行此操作的最佳方法是删除distinct,删除两个内部联接,然后添加exists过滤器。

您正在调用用户定义的函数dbo.wordcount 16次。这个功能几乎无关紧要,每行调用16次几乎可以保证很慢。由于UDF的结果仅用于排序和返回,为什么不返回原始数据,而是在中间层进行排名计算和排序呢?

然后查询变为:

select
    tb_Ecomm_Product.SKU,
    tb_Ecomm_Product.MainCategory,
    tb_Ecomm_Product.SEName,
    tb_Ecomm_Product.ProductID, 
    tb_Ecomm_Product.Name,
    (case when isnull(SalePrice, 0) != 0 then SalePrice else Price end) as SalePrice
from tb_Ecomm_Product 
where tb_Ecomm_Product.StoreID = 1
and exists (
    select null
    from tb_Ecomm_Category
    inner join tb_Ecomm_ProductCategory on tb_Ecomm_ProductCategory.CategoryID = tb_Ecomm_Category.CategoryID
    where tb_Ecomm_Product.ProductID = tb_Ecomm_ProductCategory.ProductID
    and tb_Ecomm_Category.StoreID = 1 
    and tb_Ecomm_Category.Status = 1
    and tb_Ecomm_Category.Deleted = 0
)
and Price != 0 
and isnull(case when isnull(SalePrice, 0) != 0 then SalePrice else Price end, 0) != 0 
and tb_Ecomm_Product.Status = 1
and tb_Ecomm_Product.Deleted = 0
and (
    (tb_Ecomm_Product.name like '%HWD%' or tb_Ecomm_Product.Description like '%HWD%') or
    (tb_Ecomm_Product.name like '%AquaBug%' or tb_Ecomm_Product.Description like '%AquaBug%' )
)

如果我误解了原始查询的任何方面,请告诉我,我会编辑我的答案。