SQL Server:有一种更好的方法来使用where子句编写此逻辑以提高性能

问题描述 投票:0回答:2

我仍然是编写SQL查询的新手,我想知道是否有更好的方法在以下查询中编写where子句以提高过滤结果的性能?

查询:

SELECT    
    B.col1, A.col1, A.col2   
FROM 
    tblB B  
INNER JOIN 
    tblA A ON B.ID = A.ID   
WHERE   
    ((B.T_No NOT LIKE '123%' AND b.StartDate < '2001-01-01') 
     OR
     (B.T_No NOT LIKE '234%' AND b.StartDate < '2005-01-01')
    )
    AND B.BName = 'sth'
    AND B.c_Val = 33

注意:我不应该使用主键来过滤这些结果。

谁能帮我?

sql sql-server performance where-clause
2个回答
1
投票

这是您的查询:

SELECT B.col1, A.col1, A.col2   
FROM tblB B INNER JOIN
     tblA A
     ON B.ID = A.ID   
WHERE ((B.T_No NOT LIKE '123%' AND b.StartDate < '2001-01-01') OR
       (B.T_No NOT LIKE '234%' AND b.StartDate < '2005-01-01')
      ) AND
      B.BName = 'sth' AND
      B.c_Val = 33;

where条款对性能没有太大影响。有什么区别是索引。为此,我建议tblB(BName, c_Val, StartDate, t_no, id, col)。您还需要tblA(id)上的索引(如果尚未声明为唯一或主键)。

这是查询的覆盖索引,这意味着tblB中使用的所有列都在索引中。这意味着索引可以满足查询,而无需引用数据页。


1
投票

我会针对这两个更改来优化此查询:

  1. 首先,我将查询分为两部分,结合UNION(如果你不关心删除重复项,最好是UNION ALL),但也可以使用UNION DISTINCT。这种拆分将允许MySQL更好地索引WHERE过滤器,因为它在使用OR条件时无法正确搜索索引。
  2. 添加适当的索引。

那么让我们看一下优化的查询:

(SELECT 
    B.col1, A.col1, A.col2
FROM
    tblB B
        INNER JOIN
    tblA A ON B.ID = A.ID
WHERE
    ((B.T_No NOT LIKE '123%'
        AND B.StartDate < '2001-01-01'))
        AND B.BName = 'sth'
        AND B.c_Val = 33) UNION DISTINCT (SELECT 
    B.col1, A.col1, A.col2
FROM
    tblB B
        INNER JOIN
    tblA A ON B.ID = A.ID
WHERE
    ((B.T_No NOT LIKE '234%'
        AND B.StartDate < '2005-01-01'))
        AND B.BName = 'sth'
        AND B.c_Val = 33)

关于索引:MySQL有很多因素来决定是否开始加入tblA或tblA。因此,很难说您提供的信息(没有架构和解释计划)将首先使用哪个表。因此,您还可以尝试一次添加这两个选项,并查看哪个选项表现更好:选项A:

ALTER TABLE `tblA` ADD INDEX `tblA_index_1` (`col1`, `col2`);
ALTER TABLE `tblB` ADD INDEX `tblB_index_1` (`BName`, `c_Val`, `ID`, `StartDate`, `col1`);

选项B:

ALTER TABLE `tblA` ADD INDEX `tblA_index_1` (`ID`, `col1`, `col2`);
ALTER TABLE `tblB` ADD INDEX `tblB_index_1` (`BName`, `c_Val`, `StartDate`, `col1`);
© www.soinside.com 2019 - 2024. All rights reserved.