证明SQL查询等效

你会如何​​去证明两个查询是相同的功能,例如,他们会一直都返回相同的结果集。



当我想到一个特定的查询,当我这样做,我最后做的@dougman表明,超过10%的行有关表格并比较结果,以确保没有地方出结果。

--------------解决方案-------------

你能做的最好的对比就是基于一组给定的输入,寻找任何差异2查询输出。 如果说,他们将始终返回相同的结果,所有输入端实际上取决于数据。

对于Oracle的更好,如果不是最好的办法(非常有效)就在这里(按Ctrl + F比较两个表的内容)之一:
http://www.oracle.com/technetwork/issue-archive/2005/05-jan/o15asktom-084959.html

这可以归结为:

select c1,c2,c3,
count(src1) CNT1,
count(src2) CNT2
from (select a.*,
1 src1,
to_number(null) src2
from a
union all
select b.*,
to_number(null) src1,
2 src2
from b
)
group by c1,c2,c3
having count(src1) <> count(src2);

这听起来好像是一个NP完全问题。 我不知道有一个确保消防方式来证明这种事情

这是很容易做到的。

让我们假设你的查询被命名为a和b

一减B

应该给你一个空集。 如果它没有。 那么查询将返回不同集,结果集显示你是不同的行。

然后做

B减一

应该给你一个空集。 如果这样做,则查询并返回相同的集。 如果不是空的,那么查询是在某些方面不同,结果集显示你是不同的行。

该数据库管理系统供应商一直在这一个很长很长的时间。 正如里克说,这可能是一个棘手的问题,但我不认为在问题空间的NP-完整性做出任何正式的分析已经完成。

但是,最好的办法是利用你的DBMS尽可能。 所有DBMS系统转换成SQL某种查询计划。 您可以使用此查询计划,这是查询的抽象版本,作为一个很好的起点(数据库管理系统会做优化的地段,扁平化的查询到更可行的模式)。

注:现代DBMS使用“基于成本的”分析这是整个统计信息更新不确定性,因此,查询规划,随着时间的推移,可能会改变的查询计划相同的查询。

在Oracle(取决于您的版本),你可以告诉优化器基于成本的分析与SQL提示,如切换到确定性的基于规则的分析(这将简化方案分析)

SELECT /*+RULE*/ FROM yourtable

由于8I的基于规则的优化器已被弃用,但它仍然挂起各地甚至通10G(我不知道'回合11做)。 然而,以规则为基础分析仪是不太复杂:潜在的错误率要高得多。

对于进一步的阅读一个比较通用性的,IBM已经相当丰富他们的查询优化专利。 这一次在这里对SQL转换为一个“抽象计划”的方法是一个很好的起点:http://www.patentstorm.us/patents/7333981.html

这将这样的伎俩。 如果该查询返回零行的两个查询返回相同的结果。 作为奖励,它会作为一个单独的查询,所以你不必担心设置的隔离级别,这样的数据并不两个查询之间切换。

select * from ((<query 1> MINUS <query 2>) UNION ALL (<query 2> MINUS <query 1>))

这里有一个方便的shell脚本来做到这一点:

#!/bin/sh

CONNSTR=$1
echo query 1, no semicolon, eof to end:; Q1=`cat`
echo query 2, no semicolon, eof to end:; Q2=`cat`

T="(($Q1 MINUS $Q2) UNION ALL ($Q2 MINUS $Q1));"

echo select 'count(*)' from $T | sqlplus -S -L $CONNSTR

你不知道。

如果你需要一个高水平的信心,性能的变化,例如,没有改变一个查询的输出然后测试的地狱了。

如果你需要自信..然后errrm一个非常高的水平,甚至更多的测试。

海量级的测试并不难凑齐一个SQL查询。 写一个进程,这将遍历周围的一大片/一整套可能paramenters,并调用每组PARAMS的每个查询,并写入输出相应的表。 比较两个表和你有它。

这是不完全科学的,这是我的猜测是业务方案的问题,但我不知道正式的方法来证明等效的。

也许你可以画(手)你的查询和使用维恩图的结果,看看他们是否产生同样的图。 维恩图是良好的表示的数据集,和SQL查询对数据集工作。 绘制出了文氏图可以帮助你可视化,如果2查询在功能上等同。

小心! 功能“对等”往往是基于数据的,你可以“证明”的2查询等价比较结果很多情况下,仍然是错误的,一旦以某种方式对数据的变化。

例如:

SQL> create table test_tabA
(
col1 number
)

Table created.

SQL> create table test_tabB
(
col1 number
)

Table created.

SQL> -- insert 1 row

SQL> insert into test_tabA values (1)

1 row created.

SQL> commit

Commit complete.

SQL> -- Not exists query:

SQL> select * from test_tabA a
where not exists
(select 'x' from test_tabB b
where b.col1 = a.col1)

COL1

----------

1

1 row selected.

SQL> -- Not IN query:

SQL> select * from test_tabA a
where col1 not in
(select col1
from test_tabB b)

COL1

----------

1

1 row selected.

-- THEY MUST BE THE SAME!!! (or maybe not...)

SQL> -- insert a NULL to test_tabB

SQL> insert into test_tabB values (null)

1 row created.

SQL> commit

Commit complete.

SQL> -- Not exists query:

SQL> select * from test_tabA a
where not exists
(select 'x' from test_tabB b
where b.col1 = a.col1)

COL1

----------

1

1 row selected.

SQL> -- Not IN query:

SQL> select * from test_tabA a
where col1 not in
(select col1
from test_tabB b)

**no rows selected.**

分类:SQL 时间:2015-03-15 人气:0
本文关键词: SQL,甲骨文
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.406 (s). 10 q(s)