我必须从两个数据库中获取信息。一个是ORACLE,另一个是DB2。在我的程序(C#)中,我从ORACLE数据库中获取了对象的基本信息。在第二步中,我想添加保存在DB2中的信息。 DB2中的表具有复合主键,我不确定哪种是最佳的请求方式,或者是否存在我目前看不到的替代方法。
例如:COLUMN1和COLUMN2是复合主键。
变式1:
SELECT *
FROM (SELECT COLUMN1, COLUNN2, COLUMN3, ..., COLUMN1||'_'||COLUMN2 AS ID
FROM TABLE1) AS TEMP
WHERE ID='2011_123456'
OR ID='2011_987654'
这里我认为缺点是,对于表中的每一行,字符串连接都是构建的,并且执行速度相对较慢,因为主键列已编制索引而新键不是。
变式2:
SELECT COLUMN1, COLUMN2, COLUMN3, ..., COLUMN1||'_'||COLUMN2 AS ID
FROM TABLE1
WHERE (COLUMN1='2011' AND COLUMN2='123456')
OR (COLUMN1='2011' AND COLUMN2='987654')
这个非常快,但是每当我得到一个异常SQL0954C时(应用程序堆中没有足够的存储空间来处理语句)。
变式3:
SELECT COLUMN1, COLUMN2, COLUMN3, ..., COLUMN1||'_'||COLUMN2 AS ID
FROM TABLE1
WHERE COLUMN1 IN ('2011')
AND COLUMN2 IN ('123456','987654')
与变体2相比,这个也很慢。
更多数字:TABLE1目前约有。 600k行
我尝试了变体并获得了以下执行时间:
对于100个请求的对象:
变式1:3900ms
变式2:218ms
对于400个请求的对象:
变式1:10983ms
变体2:266ms
对于500个请求的对象:
变式1:12796ms
变体2:异常SQL0954C
变式3:7061ms
只看时间我更喜欢变体2,但异常存在问题。
数据库不受我的控制,我只有SELECT权限。您认为这个用例最好的是什么?还有其他我没有看到的可能吗?
的问候,
pkoeppe
答案 0 :(得分:0)
你可以修改
的变体2吗?例如,请参阅http://oracletoday.blogspot.com/2005/11/bulk-collect_15.html
我遇到的问题与Oracle和Informix非常相似。
答案 1 :(得分:0)
变体2和3都是理智的。 1是不理智的 由于1中的计算列ID不在任何索引中,因此DB将被强制执行至少完整的索引扫描。在2和3中,DB可以使用column1和column2上的索引来过滤结果。
要了解2或3是否最佳,您需要研究这些查询的执行计划。
关于索引的另一个注释。相关索引将比2和3之间的差异重要得多。即使您只有选择权限,如果没有这样的索引,也可以建议DBA(column1,column2)上的复合索引。
修改强>
在WHERE COL IN (...)
中有许多值时,另一种常见的方法是创建一个包含所有值的临时表(如果您有权限)并改为与该临时表连接。有时您还需要在临时表上创建索引以使其表现良好
在某些DBMS中,您可以使用表值参数而不是临时表,但我找不到类似于DB2的内容。
答案 2 :(得分:0)
可以通过调整系统配置来解决SQL0954C问题。你有没有探索过那条大道? Find out more
答案 3 :(得分:0)
对于变体3,请更改
SELECT COLUMN1, COLUMN2, COLUMN3, ..., COLUMN1||'_'||COLUMN2 AS ID
FROM TABLE1
WHERE COLUMN1 IN ('2011')
AND COLUMN2 IN ('123456','987654')
要:
SELECT COLUMN1, COLUMN2, COLUMN3, ..., COLUMN1||'_'||COLUMN2 AS ID
FROM TABLE1
WHERE COLUMN1 ='2011'
AND COLUMN2 IN ('123456','987654')
如果您只搜索COLUMN1的一个值,则没有理由使用IN。