我们有一个employee_master表和一个Report_Filter表,Report_Filter包含用户输入的不同类型的过滤器,例如。状态,员工代码,国家/地区等,此report_filter也包含用户信息。表结构就像这个Report_Filter(User_Id,Report_TYpe,Report_Code)都是字符字段。根据用户输入,表格将具有类似
的值( 'User_1', 'STATUS', '01' )
( 'user_1', 'STATUS', '02' )
( 'User_1', 'EMP_CODE', 'ABC' )
( 'User_1', 'NATIONALITY', 'ALL' ) -- All means he want to see all the nationalities
现在我们正在编写像这样的查询
Select Emp_code, Emp_Name, status, nationlity
From Empolyee_Master m
Where
('All' in ( select report_code from Report_Filter where user_id = @user_id and report_type='STATUS') or m.STATUS in ( select report_code from Report_Filter where user_id = @user_id and report_type='STATUS') ) and
or m.CATEGORY in ( select report_code from Report_Filter where user_id = @user_id and report_type='NATIONALITY') ) and
or m.emp_code in ( select report_code from Report_Filter where user_id = @user_id and report_type='EMP_CODE') )
还有其他条件我们正在使用,问题是因为In子句需要花费太多时间。我们如何才能有效地更改此代码以提高性能
我们正在使用MSSQL 2014
答案 0 :(得分:1)
您应该按值过滤,而不是检索所有值,然后查看您的值是否属于它的一部分。试试这是否有帮助(只是一个例子):
替换
WHERE 'ALL' in (
select report_code from Report_Filter
where user_id = @user_id and report_type='STATUS'
)
与
WHERE EXISTS (
select 1 from Report_Filter
where user_id = @user_id and report_type='STATUS'
and report_code = 'ALL'
)
现在,在INDEX中包含列report_code
也会有所帮助(我希望你使用INDEX?)
更新 - 如果是' ALL'则跳过过滤,可以这样做:
DECLARE @statusFilter VARCHAR(20) = ... -- 'ALL' or other value
SELECT ...
WHERE @statusFilter = 'ALL'
OR EXISTS (
select 1 from Report_Filter
where user_id = @user_id and report_type='STATUS'
and report_code = @statusFilter
)
答案 1 :(得分:0)
您可以提前尝试进行过滤:
(对于你的下一个问题:这样的模型应该由你完成)
DECLARE @ReportFilter TABLE([user_id] VARCHAR(100),report_type VARCHAR(100),report_code VARCHAR(100));
INSERT INTO @ReportFilter VALUES
( 'User_1', 'STATUS', '01' )
,( 'user_1', 'STATUS', '02' )
,( 'User_1', 'EMP_CODE', 'ABC' )
,( 'User_1', 'NATIONALITY', 'ALL' );
DECLARE @Employee_Master TABLE(Emp_Code VARCHAR(100),Emp_Name VARCHAR(100), [status] VARCHAR(100), nationality VARCHAR(100));
INSERT INTO @Employee_Master VALUES
('ABC','test1','01','USA')
,('DEF','test2','99','GB')
,('ABC','test3','02','DE')
,('XYZ','test4','01','FRA');
- 这是您的查询的一部分
DECLARE @user_id VARCHAR(100)='User_1';
WITH filterSTATUS AS
(
SELECT * FROM @ReportFilter WHERE [user_id]=@user_id AND report_type='STATUS'
AND NOT EXISTS(SELECT 1 FROM @ReportFilter WHERE [user_id]=@user_id AND report_type='STATUS' AND report_code='ALL')
)
,
filterEMPCODE AS
(
SELECT * FROM @ReportFilter WHERE [user_id]=@user_id AND report_type='EMP_CODE'
AND NOT EXISTS(SELECT 1 FROM @ReportFilter WHERE [user_id]=@user_id AND report_type='EMP_CODE' AND report_code='ALL')
)
,filterNATIONALITY AS
(
SELECT * FROM @ReportFilter WHERE [user_id]=@user_id AND report_type='NATIONALITY'
AND NOT EXISTS(SELECT 1 FROM @ReportFilter WHERE [user_id]=@user_id AND report_type='NATIONALITY' AND report_code='ALL')
)
SELECT *
FROM @Employee_Master AS em
WHERE (SELECT COUNT(*) FROM filterSTATUS)=0 OR em.[status] IN (SELECT x.report_code FROM filterSTATUS AS x)
AND (SELECT COUNT(*) FROM filterEMPCODE)=0 OR em.Emp_Code IN (SELECT x.report_code FROM filterEMPCODE AS x)
AND (SELECT COUNT(*) FROM filterNATIONALITY)=0 OR em.nationality IN (SELECT x.report_code FROM filterNATIONALITY AS x);
对于给定集,这将返回
Emp_Code Emp_Name status nationality
ABC test1 01 USA
ABC test3 02 DE