是否存在短路mysql查询的“最佳方法”

时间:2014-01-31 20:43:42

标签: mysql optimization query-optimization short-circuiting

我遇到的情况是我根据用户提供的标准组装查询,并希望找出最有效的方法。

如果我有一个看起来像这样的表:

int id | varchar phone | varchar email | varchar RFID

并且用户将传入一个数组,该数组定义了他们想要查找用户的顺序(和项目),其中*可能如下所示:

["id","email","phone"]

或者看起来像这样:

["email"]

或者看起来像这样:

["phone","rfid"]

或这4个字段的任何其他可能组合。

根据我收到的内容,我需要按照这些字段到达的顺序查看用户,如果找到匹配项,我不想继续查看。

换句话说,如果输入是

["email","rfid","phone"]

我查看数据库并找到一个提供电子邮件的用户,我不想继续查看他们的rfid是否也匹配,我只想返回所述用户。 但是,如果我没有找到这样的电子邮件,那么我想转到rfid。

所以,在我完成的各种测试中(主要是在case子句中使用where语句),我的结果非常糟糕。经常花费几秒钟来返回一个值,而不是在我简化where以搜索单个字段时采用<50ms。

我应该注意所有这些字段都已编入索引。

所以...我的问题是,我应该只是咬住子弹并进行与传入数组中的项目一样多的sql调用,或者是否有一些非常有效的方法来构建一个不会陷入困境的单个查询系统就像我的各种尝试一样。

我认识到这可能是一个过于抽象的问题,但我希望有一些机制可以让我只是忽视这种用途。

1 个答案:

答案 0 :(得分:2)

我认为没有什么好的方法可以在SQL中进行短路。您可以构造一个WHERE子句,使用OR来组合标记,但这样做通常会阻止它使用索引。你可以使用这样的UNION

SELECT * FROM
    (SELECT 1 precedence, table.*
     FROM table
     WHERE field1 = 'value'
     UNION
     SELECT 2 precedence, table.*
     FROM table
     WHERE field2 = 'value'
     ...
    ) x
ORDER BY precedence
LIMIT 1

使用输入数组中的字段名称替换field1field2等。这将在一个查询中产生所需的结果,但它必须执行所有子查询,它不会短路。

最好的解决方案可能是在应用程序代码中解决它。循环输入中的字段,并仅对该字段执行查询。当你得到一个结果时,跳出循环并返回它。