我正在编写一个存储过程,其功能是获取许多参数(由最终用户填充)并执行搜索。但是,如果参数没有值,则不应将其包含在WHERE子句中。为此,我正在检查参数作为OR子句的第一部分,如下所示:
... WHERE (param1 = '' OR field1 = param1) AND (param2 = '' OR field2 = param2) ...
然后我将其合并到一般的选择语句中,如下所示:
SELECT *
FROM table1 t1
WHERE (param1 = '' OR t1.field1 = param1)
请注意为清晰起见,我在此示例中仅包含一个参数。真实查询包含多个参数和字段比较。
这样可以正常运行并且运行得很快(例如'真实'查询会在大约0.5秒内返回结果)。
到目前为止一切顺利。但是,当引入连接表时,事情就开始出错了。例如,如果我执行下面的查询,则需要更长的时间(实际查询需要3-4秒):
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
ON t1.table2Id = t2.id
WHERE (param1 = '' OR t2.field1 = param1)
请注意,现在将参数与已结合的表格(table2)中的字段进行比较。
请注意,在这两个示例中,运行查询时我确保使用值填充param1。
现在,如果我删除上述WHERE子句的param1 = '' OR
部分,它的运行速度与之前未加入的查询一样快。
我的表中使用的字段当前都没有被编入索引,尽管我已经尝试了这个并且它对我遇到的问题没有任何影响。
那么,有人可以向我解释为什么第一个查询(单个表)工作很快但第二个查询(连接表)花费的时间不成比例吗?
非常感谢提前。
答案 0 :(得分:0)
尝试将第一个条件添加为JOIN
的一部分,看看是否对您有帮助。
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
ON t1.table2Id = t2.id AND
t2.field1 = param1
答案 1 :(得分:0)
您可以尝试制作视图,并在连接语句中使用该视图的结果。
CREATE VIEW `VW_my_simple_table_view_name` AS SELECT *
FROM table1 t1
WHERE (param1 = '' OR t1.field1 = param1)
然后查询看起来像这样(可能需要改编)
SELECT *
FROM VW_my_simple_table_view_name t1
LEFT JOIN table2 t2
ON t1.table2Id = t2.id
WHERE (t2.field1 = param1)
答案 2 :(得分:0)
我终于解决了这个问题,删除了table2上的LEFT JOIN
并将其替换为简单的JOIN
,如下所示:
SELECT *
FROM table1 t1
JOIN table2 t2
ON t1.table2Id = t2.id
WHERE (param1 = '' OR t2.field1 = param1)
说实话,绝对没有理由让这个成为LEFT JOIN。我只是没想到!无论如何,非常感谢Evan和Michael的帮助和建议(以及他们的超快反应)。