2013-04-05 53 views
0

我在写一个存储过程,它的功能是获取许多参数(由最终用户填充)并执行搜索。但是,如果参数没有值,则不应将其包含在WHERE子句中。为此,我本人对参数进行检查作为or子句的第一部分,像这样:通过连接表上的参数检查减慢MySQL查询

... WHERE (param1 = '' OR field1 = param1) AND (param2 = '' OR field2 = param2) ... 

我已经然后将这一成普通的SELECT语句,像这样:

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) 

请注意该参数现在被比作场的连接表(表2)。

请注意,在这两个例子中,运行查询时,我已经确保参数1中填充了值。

现在,如果我删除上述WHERE子句的param1 = '' OR部分,它的运行速度与以前的未连接查询相同。

我的表中使用的字段都没有索引,尽管我已经尝试了这一点,但对于我遇到的问题没有任何影响。

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

非常感谢提前。

回答

0

我终于通过对表2的去除LEFT JOIN并用简单JOIN按照下面替换它解决了这个问题:

SELECT * 
FROM table1 t1 

JOIN table2 t2 
ON t1.table2Id = t2.id 

WHERE (param1 = '' OR t2.field1 = param1) 

说实话,绝对没有理由让它成为LEFT JOIN。我只是没有想到!无论如何,非常感谢埃文和迈克尔的帮助和建议(以及他们的超级快速反应)。

0

尝试添加第一个条件作为JOIN的一部分,看看是否有帮助。

SELECT * 
FROM table1 t1 

LEFT JOIN table2 t2 
ON t1.table2Id = t2.id AND 
t2.field1 = param1 
+0

谢谢埃文。我按照你的建议尝试过,但是现在当param1有一个值时我没有得到结果。 – 2013-04-05 12:07:36

+0

@JohnP查看更新 - 只删除最后一行 – 2013-04-05 13:22:20

+0

对不起埃文。不幸的是,现在我不能没有价值地'过滤'任何参数。 – 2013-04-05 13:35:19

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) 
+0

感谢您的建议,但我不确定这种方法是否有效。例如,我将参数与table2中的字段进行了比较,实际上我并没有与table1的任何字段进行比较。 – 2013-04-05 12:15:39