在多列中搜索多个值时减少嵌套循环

时间:2019-06-05 18:34:20

标签: sql oracle nested-loops oracle12c

我试图确定像EXISTS或COALESCE之类的函数在搜索可能出现在16个不同列中的300个值的任何匹配项时是否可以减少嵌套循环的使用。

用户提供了一个类似于以下示例的查询,并要求将其应用到大型仓库环境中,该环境无法非常有效地扩展。添加索引不是一种选择。我可以使用WITH子句来容纳300个用于查找的代码,但无法确定一旦找到第一个匹配项并移至下一条记录,是否有助于使查询中止表扫描。

SELECT
 A.product_id

FROM
  A inner join B on A.id = B.id
    inner join C on A.id = C.id

WHERE
   B.code1 in ('x1','x2','x3', ... 'x298', 'x299', 'x300')
or B.code2 in ('x1','x2','x3', ... 'x298', 'x299', 'x300')
or C.code3 in ('x1','x2','x3', ... 'x298', 'x299', 'x300')
 ...
or C.code15 in ('x1','x2','x3', ... 'x298', 'x299', 'x300')
or C.code16 in ('x1','x2','x3', ... 'x298', 'x299', 'x300')

虽然提供的代码有效,但是成本很高,我希望能帮助您改善执行时间。

2 个答案:

答案 0 :(得分:1)

一个简单的改进就是将其分为两个查询:

this

正如我在评论中所说,每个// Set up the alert builder val builder = AlertDialog.Builder(context) builder.setTitle("Choose some animals") // Add a checkbox list val animals = arrayOf("horse", "cow", "camel", "sheep", "goat") val checkedItems = booleanArrayOf(true, false, false, true, false) builder.setMultiChoiceItems(animals, checkedItems) { dialog, which, isChecked -> // The user checked or unchecked a box } // Add OK and Cancel buttons builder.setPositiveButton("OK") { dialog, which -> // The user clicked OK } builder.setNegativeButton("Cancel", null) // Create and show the alert dialog val dialog = builder.create() dialog.show() SELECT A.product_id FROM A JOIN B ON A.id = B.id WHERE B.code1 in ('x1','x2','x3', ... 'x298', 'x299', 'x300') OR B.code2 in ('x1','x2','x3', ... 'x298', 'x299', 'x300') UNION ALL -- or UNION to remove duplicates SELECT A.product_id FROM A JOIN C ON A.id = C.id WHERE C.code3 in ('x1','x2','x3', ... 'x298', 'x299', 'x300') OR ... C.code15 in ('x1','x2','x3', ... 'x298', 'x299', 'x300') OR C.code16 in ('x1','x2','x3', ... 'x298', 'x299', 'x300'); 每行一个表将是更好的数据模型。

答案 1 :(得分:0)

尝试加入代码列表。我很好奇这是否会改善您的表现:

select A.product_id
from A
inner join B on B.id = A.id
inner join C on C.id = A.id
inner join (values ('x1'),('x2'),('x3'), ... ('x298'), ('x299'), ('x300')) as v(code)
    on v.code = B.code1 
    or v.code = B.code2
    or v.code = C.code3
    ...
    or v.code = C.code16

或者,您可以取消B和C表的透视图,以便将所有codeN列值都放在一列中,然后按300个值过滤该单列。