我有4个表,即emp_table
,project_table
,dept_table
和team_table
。我在主表中存储了相关项目,部门和团队的ID,即emp_table
。我编写了以下查询来检索所有细节。
SELECT
a.emp_id ,
a.emp_name,
a.emp_manager,
IF(a.emp_dept = 0,'',c.dept_name),
IF(a.emp_project = 0,'',b.proj_name),
IF(a.emp_team = 0,'',d.team_name)
FROM
emp_table a,
project_table b,
dept_table c,
team_table d
WHERE
(CASE WHEN a.emp_project = 0 THEN 1=1 ELSE a.emp_project = b.proj_id END)
AND (CASE WHEN a.emp_dept = 0 THEN 1=1 ELSE a.emp_dept = c.dept_id END)
AND (CASE WHEN a.emp_team = 0 THEN 1=1 ELSE a.emp_team = d.team_id END)
GROUP BY a.emp_id
ORDER BY emp_name
表emp_table
有近1000行。其余表很小(最多20行)。
查询需要6秒才能执行。我想改善执行时间。请让我知道我该怎么做。任何改进的建议将不胜感激。感谢。
答案 0 :(得分:3)
使用旧式隐式连接(作为逗号分隔的FROM
子句)会使您的查询尝试难以理解,但检查它我正在考虑您正在寻找的实际上是一个简单的{ {1}}来自LEFT JOIN
的3个表格。
使用显式emp_table
语法更易于阅读,并且无需使用所有复杂的JOIN
语句和CASE
。
我还删除了IF
,因为没有使用聚合函数。我将其替换为GROUP BY
以删除行。
DISTINCT
这些SELECT
DISTINCT
a.emp_id ,
a.emp_name,
a.emp_manager,
/* Use COALESCE to convert NULLs to '' since the LEFT JOIN will return NULL */
COALESCE(c.dept_name, '') AS dept_name,
COALESCE(b.project_name, '') AS project_name,
COALESCE(d.team_name, '') AS team_name
FROM
emp_table a
/* All joins are LEFT JOIN so non-matching will return NULL in the emp_table side */
LEFT JOIN project_table b ON a.emp_project = b.proj_id
LEFT JOIN dept_table c ON a.emp_dept = c.dept_id
LEFT JOIN team_table d ON a.emp_team = d.team_id
ORDER BY emp_name
的成功而不是检查零的LEFT JOIN
语句取决于CASE
之类的缺席。假设自动递增ID,这似乎是一个安全的赌注。
现在,假设您已在dept_id = 0
上正确定义了PRIMARY KEYS
并在proj_id, dept_id, team_id
中的相关列上正确定义了FOREIGN KEYS
,那么性能应该非常出色,因为MySQL将全部使用可用的索引。
您的emp_table
定义应该类似于以下内容,正确调整正确的数据类型和长度......
emp_table