通过连接表上的参数检查减慢MySQL查询

时间:2013-04-05 11:46:02

标签: mysql

我正在编写一个存储过程,其功能是获取许多参数(由最终用户填充)并执行搜索。但是,如果参数没有值,则不应将其包含在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部分,它的运行速度与之前未加入的查询一样快。

我的表中使用的字段当前都没有被编入索引,尽管我已经尝试了这个并且它对我遇到的问题没有任何影响。

那么,有人可以向我解释为什么第一个查询(单个表)工作很快但第二个查询(连接表)花费的时间不成比例吗?

非常感谢提前。

3 个答案:

答案 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的帮助和建议(以及他们的超快反应)。