我仍然是编写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
注意:我不应该使用主键来过滤这些结果。
谁能帮我?
这是您的查询:
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
中使用的所有列都在索引中。这意味着索引可以满足查询,而无需引用数据页。
我会针对这两个更改来优化此查询:
那么让我们看一下优化的查询:
(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`);