mysql回退WHERE语句

时间:2013-10-10 16:36:56

标签: mysql sql performance where

假设我这样做:

SELECT * FROM table WHERE field2 = '2019@162440' OR field2 LIKE '%%2019@%%';

在这种情况下,它将尝试执行BOTH field2 = '2019@162440'field2 LIKE '%%2019@%%'条件的匹配(即,它将搜索与这些条件匹配的行,因此需要更多的计算能力来尝试查找即使已找到匹配field2 = '2019@162440'

的行,也会匹配这两个条件的行

有没有办法通过改进查询来指示mysql,只有在条件field2 LIKE '%%2019@%%'与任何内容不匹配时才尝试执行field2 = '2019@162440',以便查询变得更有效

IE。我本质上希望mysql只在没有匹配field2 LIKE '%%2019@%%'的行时才尝试查找匹配field2 = '2019@162440'的行。如果找到与field2 = '2019@162440'匹配的行,请勿尝试匹配field2 LIKE '%%2019@%%'

此外,没有子查询

2 个答案:

答案 0 :(得分:1)

首先让我说我不是MySQL的专家。它几乎没有像其他DBMS那样优化,因此以下查询可能实际上不会减少执行时间。但它值得一试......

如果field2被编入索引,这可能是一个非常快速的解决方案:

-- Get results where field2 = '2019@162440'
SELECT  *
FROM    table
WHERE   field2 = '2019@162440'
-- Append...
UNION
-- Get results where field2 LIKE '%%2019@%%' but only
-- if there are no rows where field2 = '2019@162440'
SELECT  *
FROM    table
WHERE   NOT EXISTS(
            SELECT  *
            FROM    table
            WHERE   field2 = '2019@162440'
        )
    AND field2 LIKE '%%2019@%%'

您将运行最快的查询并选择所有结果。然后,附加包含EXISTS的第二个较慢的查询。如果子查询包含任何行,EXISTS子句将返回true,这应该使整个第二个查询短路并防止它运行(因此追加0行)。但是,如果第一个查询返回0行,则第二个查询将启动并运行较慢的LIKE比较。

答案 1 :(得分:0)

我能做的最好的事情是使用FOUND_ROWS()函数和UNION:

SELECT *  
FROM t  
WHERE field2 = '2019@162440'

UNION ALL

SELECT *  
FROM t   
WHERE FOUND_ROWS() = 0 
      AND field2 LIKE '%%2019@%%'

SQL Fiddle Demo