Sql 条件where子句导致糟糕的性能Firebird
Firebird不知道如何执行条件where。或者我就是这么想的 第一个查询在15毫秒后返回值Sql 条件where子句导致糟糕的性能Firebird,sql,firebird,firebird2.5,Sql,Firebird,Firebird2.5,Firebird不知道如何执行条件where。或者我就是这么想的 第一个查询在15毫秒后返回值 SELECT DISTINCT A.MANID, A.DISNO, A.DISID FROM TABLEB B INNER JOIN TABLEA A ON (A.ITEM_ID = B.ITEM_ID) WHERE
SELECT DISTINCT
A.MANID,
A.DISNO,
A.DISID
FROM
TABLEB B
INNER JOIN TABLEA A ON (A.ITEM_ID = B.ITEM_ID)
WHERE
(
(POSITION('%' IN :ISEARCH) = 0 AND B.CATID = :ISEARCH)
)
第二个查询需要40多秒,所有内容都与OR条件有关
SELECT DISTINCT
A.MANID,
A.DISNO,
A.DISID
FROM
TABLEB B
INNER JOIN TABLEA A ON (A.ITEM_ID = B.ITEM_ID)
WHERE
(
(POSITION('%' IN :ISEARCH) = 0 AND B.CATID = :ISEARCH) OR
POSITION('%' IN :ISEARCH) <> 0
)
选择DISTINCT
曼尼德,
不,
双歧杆菌
从…起
表B
上的内部联接表(A.ITEM\u ID=B.ITEM\u ID)
哪里
(
(位置(“%”在:ISEARCH中)=0且B.CATID=:ISEARCH)或
位置(“%”在:ISEARCH中)0
)
我怎样才能让firebird在这种情况下表现出来?有点牵强,我对firebird不太熟悉,但对于这种特殊情况,我建议尝试一下
(
(POSITION('%' IN :ISEARCH) = 0 AND B.CATID = :ISEARCH) OR
POSITION('%' IN :ISEARCH) <> 0
)
(
(位置(“%”在:ISEARCH中)=0且B.CATID=:ISEARCH)或
位置(“%”在:ISEARCH中)0
)
写得像
(
(POSITION('%' IN :ISEARCH) <> 0 OR B.CATID = :ISEARCH)
)
(
(位置(“%”位于:ISEARCH)0或B.CATID=:ISEARCH)
)
哪个对查询优化器更有意义?
它仍然是一个或
,许多RDBMS不喜欢或
但值得一试
最坏的情况是,您可以尝试将语句拆分为两个单独的查询,然后将所有查询重新组合在一起,其中一个查询处理
位置('%'IN:ISEARCH)0
,另一个查询处理B.CATID=:ISEARCH
。这种方法的问题可能是需要再次过滤掉的条目增加了一倍。(又名:一罐新的蠕虫…每个蠕虫的计划是什么样的?这将是您了解当前情况的最大线索。如果CATID
上有索引,则可以优化第一个查询,但第二个查询将是自然扫描。您可能希望使用联合ALL
尝试两个单独的查询,并查看其执行情况。是的,Firebird似乎无法处理第二个查询。OR条件立即抛出索引并进行全表扫描,即使在强制执行计划时也是如此。我必须使用多个查询来接近我的解决方案。“USE17171567”查询计划是在查询准备时间上决定的,那时优化器不知道参数的值是:ISEARCH将有什么,所以它根本不考虑索引,因为如果第二个条款应用它不能使用它。这个SQL试图做什么?如果没有%
,您是否尝试使用=
,但如果,则使用类似于的:ISEARCH
具有%
?因为在没有通配符的字符串上类似于的应该与=
相同。谢谢你的建议。Mark R.给了我们一个提示,为什么我们不应该在Firebird中的WHERE子句中使用该条件。此外,我们正在讨论v.2.1,它缺少v.2.5带来的一些改进。再次感谢。