首先,我在Oracle Docs上看到了select语句。
我有一些关于oracle选择行为的问题,当我的查询包含select,join,where时。
请参阅以下信息:
My sample table:
[ P_IMAGE_ID ]
IMAGE_ID (PK)
FILE_NAME
FILE_TYPE
...
...
[ P_IMG_TAG ]
IMG_TAG_ID (PK)
IMAGE_ID (FK)
TAG
...
...
我的要求是:当标签为“70702”时,获得不同的图像。
SELECT DISTINCT PID.IMAGE_ID
, PID.FILE_NAME
FROM P_IMAGE_ID PID
INNER JOIN P_IMG_TAG PTAG
ON PTAG.IMAGE_ID = PID.IMAGE_ID
WHERE PTAG.TAG = '70702';
我认为查询行为应该是:
join table -> hint where cause -> distinct select
我使用Oracle SQL开发人员来获取解释计划:
方法1费用 76 。
SELECT DISTINCT PID.IMAGE_ID
, PID.FILE_NAME
FROM P_IMAGE_ID PID
WHERE PID.IMAGE_ID IN
(
SELECT PTAG.IMAGE_ID
FROM P_IMG_TAG PTAG
WHERE PTAG.TAG = '70702'
);
我认为第二个查询行为应该是:
hint where cause -> hint where cause -> distinct select
我也使用Oracle SQL开发人员来获取解释计划:
方法2也花费 76 。为什么?
我相信当我尝试首先减少数据库进程并避免连接表时,查询性能应该优于表连接查询,但现在当我测试它时,我很困惑,为什么2方法成本相等? 或者我误解了什么?
我的问题清单:
为什么2种方法的成本相等?
如果子选择Tag = '70702'
的结果超过千或百万或更多,使用连接表应该更好吗?
如果子选择Tag = '70702'
的结果最少,使用sub select for reduce data查询过程会更好吗?
当我使用方法1时Select -> Join -> Where -> Distinct
表示数据库进程表在提示之前加入哪个原因正常?
当我移动提示导致Tag = '70702'
加入原因时,有人告诉我
(即INNER JOIN P_IMG_TAG PTAG ON PAT.IMAGE_ID = PID.IMAGE_ID AND PTAG.TAG = '70702'
)它的表现可能会更好吗?
我读了主题subselect vs outer join和subquery or inner join,但两者都是针对SQL Server的,我不确定它可能与Oracle数据库一样。
答案 0 :(得分:0)
DBMS接受您的查询并执行某些内容。但它不会按照它们在SQL语句中出现的顺序执行与SQL语句部分对应的步骤。
阅读"relational query optimization",这也可以被称为"关系查询实现"。例如for Oracle。
任何语言处理器都将声明和调用作为输入,并根据内部数据结构和操作实现所描述的行为,可能通过一个或多个级别的"中间代码"在"虚拟机"上运行,最终到达物理机器。但即使只是保留输入语言,SQL查询也可以重新排列到其他SQL查询中,返回相同的值,但在简单下执行明显更好和一般实施假设。就像你知道你的问题的查询总是为给定的数据库返回相同的东西,DBMS可以知道。它如何知道的一部分是,有很多规则可以用于获取关系代数表达式并生成不同但相同值的表达式。某些重写规则适用于某些有限的情况。有些规则考虑了SQL级关系,如主键,唯一列,外键和其他约束。其他规则使用面向实现的SQL级事物,如索引和统计信息。这是"关系查询重写"关系查询优化的一部分。
即使两个不同但等效的查询生成不同的计划,成本也可能相似,因为计划非常相似。这里,HASH和SORT索引都是UNIQUE。 (知道每个查询的少数顶级计划是什么会很有趣。很可能两者都是相同的,但是这个计划更直接来自于特殊的输入表达式是在没有什么区别时提供的表达式。)
让DBMS找到好的查询计划的方法是编写可以找到的最自然的查询表达式。