我的查询需要很长时间才能执行。我等了大约10分钟,但仍未完成执行。
查询看起来像这样:
SELECT
one.ID,
two.NAME,
two.STATUS,
four.KEY,
four.VALUE,
count(one.ID) as num
FROM TABLE_ONE one, TABLE_TWO two, TABLE_THREE three, TABLE_FOUR four
WHERE one.STATE='RED'
AND (two.STATUS='ON' OR two.STATUS='OFF')
AND (
four.KEY='FINAL'
OR four.KEY='LIMIT'
OR (
four.KEY='MODE'
AND (
four.VALUE='T'
OR four.VALUE='R')))
GROUP BY one.ID, two.NAME, two.STATUS, four.KEY, four.VALUE
ORDER BY group_name ASC;
我有另一个相同的查询,但执行速度非常快(执行时间约为1秒)。
以下是该查询:
SELECT
one.ID,
two.NAME,
two.STATUS,
four.KEY,
four.VALUE,
count(one.ID) as num
FROM TABLE_ONE one
INNER JOIN TABLE_TWO two
ON one.ID=two.ID
INNER JOIN TABLE_THREE three
ON two.ID=three.GROUP_ID
INNER JOIN TABLE_FOUR four
ON three.ID=four.ID
WHERE one.STATE='RED'
AND (two.STATUS='ON' OR two.STATUS='OFF')
AND (
four.KEY='FINAL'
OR four.KEY='LIMIT'
OR (
four.KEY='MODE'
AND (
four.VALUE='T'
OR four.VALUE='R')))
GROUP BY one.ID, two.NAME, two.STATUS, four.KEY, four.VALUE
ORDER BY group_name ASC;
我有点困惑为什么INNER JOIN
的查询执行速度非常快(大约1秒)而没有花费很长时间的查询(等待大约10分钟但仍未完成执行)。
如果没有INNER JOIN
加速执行时间,我可以对查询做些什么吗?
我正在使用ORACLE。
答案 0 :(得分:2)
在第一个查询中,表并未真正连接到任何列。结果称为cross join
。两个表返回行之间的交叉连接等于第一个表中的行数乘以第二个表中的行数。
Inner join
根据给定的列集合加入。
答案 1 :(得分:0)
您的长时间运行查询没有连接条件来将一个表与另一个表相关联。因此,它正在创建每个表中所有记录的笛卡尔积。因此,如果每个表有10行,它将在执行聚合函数之前生成10 * 10 * 10 * 10 = 10,000个结果行。更大的桌子变得更糟。如果每个表有1,000行,那么最终会生成1,000,000,000,000行。
您的快速查询具有连接条件,这会显着减少结果集中的行数,这就是为什么它的性能更高。
答案 2 :(得分:0)
假设你有ID的N值。在第一个查询中,您将创建N * N * N * N(或N ^ 4)行。
在第二个中你将创建N行。
大O符号:
O(N^4)
VS
O(N)
现在你有一个影响力的现实世界的例子。