PostgreSQL查询优化:获取无地址且当前Active为TRUE的员工ID
SQL查询优化:找出无地址记录且当前活跃的员工
首先你的原查询存在逻辑矛盾和语法错误,这不仅会导致结果不符合需求,还会拖慢查询速度:
- 你先通过
emp.empid = add.empid关联了address表,紧接着又用emp.emp_id not in (...)排除该表的所有记录,这会直接返回空结果,完全违背你的业务需求 - 字段名写错:
emp.val应该是emp.value,emp.emp_id应该是emp.empid,这会导致语法错误或无匹配数据 - 冗余关联:关联
address表完全是多余操作,平白增加了数据库的计算量
修正后的高效查询
方案1:LEFT JOIN + IS NULL(直观易懂)
SELECT emp.empid FROM schema1.employees emp LEFT JOIN schema2.address add ON emp.empid = add.empid WHERE emp.attribute = 'ACTIVE' AND emp.value = 'TRUE' AND CURRENT_DATE BETWEEN emp.start_date AND emp.end_date AND add.empid IS NULL LIMIT 20;
方案2:NOT EXISTS(性能更优,适合大数据量场景)
SELECT emp.empid FROM schema1.employees emp WHERE emp.attribute = 'ACTIVE' AND emp.value = 'TRUE' AND CURRENT_DATE BETWEEN emp.start_date AND emp.end_date AND NOT EXISTS ( SELECT 1 FROM schema2.address add WHERE add.empid = emp.empid ) LIMIT 20;
进一步提速的优化手段
- 添加索引:
- 给
schema1.employees建复合索引:CREATE INDEX idx_emp_active_current ON schema1.employees (attribute, value, start_date, end_date, empid);,这个索引能让数据库直接定位到当前活跃的员工,不用全表扫描 - 给
schema2.address的empid字段建索引:CREATE INDEX idx_add_empid ON schema2.address (empid);,加速判断员工是否有地址记录的查找
- 给
- 去掉冗余操作:你的需求中每个员工的当前活跃记录应该是唯一的,所以不需要
DISTINCT,去掉它能减少排序去重的开销 - 确保字段类型正确:
start_date和end_date要用DATE类型,不要存成字符串,否则日期范围判断会变慢
内容的提问来源于stack exchange,提问作者Johny
相关产品推荐
相关产品推荐

