SQL 查询执行计划和优化(索引)
SQL query execution plan and optimization (index)
我必须获取查询的执行计划,我这样做了:
set timing on
set autotrace on
select d.department_name,e.first_name,e.last_name
from employees e, departments d
where e.department_id = d.department_id and d.manager_id=e.employee_id and e.salary > 2500
group by d.department_name,e.first_name,e.last_name;
那么,方案就得到了:
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 315051678
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 495 | 7 (15)| 00:00:01 |
| 1 | HASH GROUP BY | | 11 | 495 | 7 (15)| 00:00:01 |
|* 2 | HASH JOIN | | 11 | 495 | 6 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| DEPARTMENTS | 11 | 209 | 3 (0)| 00:00:01 |
|* 4 | TABLE ACCESS FULL| EMPLOYEES | 105 | 2730 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID" AND
"D"."MANAGER_ID"="E"."EMPLOYEE_ID")
3 - filter("D"."MANAGER_ID" IS NOT NULL)
4 - filter("E"."SALARY">2500)
现在,关于谓词信息的最后一点,我必须使用类似以下方法优化执行计划:创建索引...来解决最后三点。
我该怎么做?我对此一无所知!提前致谢!
是的,根据您在那些 table 中的数据量,具有索引应该有助于提高性能。您需要检查两个加入的 table 之间是否存在任何引用完整性。
您可以通过 运行 这些查询检查是否已经在 SQL 语句中使用的 table 列上创建了任何索引,用数据库架构替换您的 tables 居住在:
SELECT *
FROM
all_indexes
WHERE
table_name = 'table_name';
这里也有类似的回复,
如果没有为这些列列出记录,那么您可能希望使用以下 DDL 为每个 table 创建一个基本索引(您可能需要稍微调整一下):
CREATE INDEX idx_depts_id ON departments (department_id);
CREATE INDEX idx_depts_mgr_id ON departments (manager_id);
CREATE INDEX idx_employees_dept_id ON employees (department_id);
CREATE INDEX idx_employee_mgr_id ON employees (manager_id);
同样,您可能需要进行一些调整。索引创建可能会非常复杂,最后并不是所有解释普通谓词的提及都需要补救,尤其是当查询在允许的阈值内执行时。在某些情况下过度调整可能会使性能变差。您只需进行测试以确保它符合您的要求。
索引并不总能提高数据库性能。通过简单的完整 table 扫描比不断遍历 b-tree 索引更好地检索大部分行。
索引通常只在您检索一小部分行时才有用。如果数据完全真实,salary > 2500
returns 几乎所有行。在这种情况下,散列连接是连接两个 table 的最佳方式。
这可能有助于解释 为什么 您想要优化查询。真的运行慢吗?这是您只需要使用索引的家庭作业吗?或者别的什么?
我必须获取查询的执行计划,我这样做了:
set timing on
set autotrace on
select d.department_name,e.first_name,e.last_name
from employees e, departments d
where e.department_id = d.department_id and d.manager_id=e.employee_id and e.salary > 2500
group by d.department_name,e.first_name,e.last_name;
那么,方案就得到了:
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 315051678
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 495 | 7 (15)| 00:00:01 |
| 1 | HASH GROUP BY | | 11 | 495 | 7 (15)| 00:00:01 |
|* 2 | HASH JOIN | | 11 | 495 | 6 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| DEPARTMENTS | 11 | 209 | 3 (0)| 00:00:01 |
|* 4 | TABLE ACCESS FULL| EMPLOYEES | 105 | 2730 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID" AND
"D"."MANAGER_ID"="E"."EMPLOYEE_ID")
3 - filter("D"."MANAGER_ID" IS NOT NULL)
4 - filter("E"."SALARY">2500)
现在,关于谓词信息的最后一点,我必须使用类似以下方法优化执行计划:创建索引...来解决最后三点。
我该怎么做?我对此一无所知!提前致谢!
是的,根据您在那些 table 中的数据量,具有索引应该有助于提高性能。您需要检查两个加入的 table 之间是否存在任何引用完整性。
您可以通过 运行 这些查询检查是否已经在 SQL 语句中使用的 table 列上创建了任何索引,用数据库架构替换您的 tables 居住在:
SELECT *
FROM
all_indexes
WHERE
table_name = 'table_name';
这里也有类似的回复,
如果没有为这些列列出记录,那么您可能希望使用以下 DDL 为每个 table 创建一个基本索引(您可能需要稍微调整一下):
CREATE INDEX idx_depts_id ON departments (department_id);
CREATE INDEX idx_depts_mgr_id ON departments (manager_id);
CREATE INDEX idx_employees_dept_id ON employees (department_id);
CREATE INDEX idx_employee_mgr_id ON employees (manager_id);
同样,您可能需要进行一些调整。索引创建可能会非常复杂,最后并不是所有解释普通谓词的提及都需要补救,尤其是当查询在允许的阈值内执行时。在某些情况下过度调整可能会使性能变差。您只需进行测试以确保它符合您的要求。
索引并不总能提高数据库性能。通过简单的完整 table 扫描比不断遍历 b-tree 索引更好地检索大部分行。
索引通常只在您检索一小部分行时才有用。如果数据完全真实,salary > 2500
returns 几乎所有行。在这种情况下,散列连接是连接两个 table 的最佳方式。
这可能有助于解释 为什么 您想要优化查询。真的运行慢吗?这是您只需要使用索引的家庭作业吗?或者别的什么?