假设我有两个表tab1,tab2。在这两个表的所有varchar列上创建的全文索引。然后发出以下SQL:
SELECT *
FROM tab1 a
JOIN tab2 b on a.ID = b.ID
WHERE CONTAINS(a.*, @keystring)
OR CONTAINS(b.*,@keystring)
这很慢(差不多30秒)。但是如果我发出以下SQL:
SELECT *
FROM tab1 a
JOIN tab2 b on a.ID = b.ID
WHERE CONTAINS(a.*, @keystring)
......或:
SELECT *
FROM tab1 a
JOIN tab2 b on a.ID = b.ID
WHERE CONTAINS(b.*,@keystring)
表现相当不错(不到第二次)
如何解决此问题?
答案 0 :(得分:2)
你试过了吗?
SELECT *
FROM tab1 a
JOIN tab2 b on a.ID = b.ID
WHERE CONTAINS(a.*, @keystring)
UNION
SELECT *
FROM tab1 a
JOIN tab2 b on a.ID = b.ID
WHERE CONTAINS(b.*,@keystring)
如果您不关心键串是否同时存在重复项,请使用UNION all。
查看执行计划以查看差异,但OR经常会使查询运行得更慢。
答案 1 :(得分:1)
真正的问题是,如果“OR”到位,则无法选择正确的索引,因为“正确”索引将取决于每一行的第一次评估的结果。因此,DBMS选择一个索引(最可能是“OR”的第一部分的正确索引),并且如果第一个评估返回为“假”,则运行第二个未编制索引的索引。这使它变慢。这种表现在很大程度上取决于第一次评估返回的频率为“假”。