WHERE 与具有多个 IFs/LIKEs 的 HAVING 计算字段

WHERE vs HAVING calculated field with multiple IFs/LIKEs

如果我在使用 having 时没有弄错,查询将在没有任何过滤器的情况下执行,然后代码遍历所有结果以应用过滤器。但在这种情况下,我使用多个 Like//If 来计算我的订单。我想知道什么会更好:

SELECT Page.*, 

if  (`flags` LIKE CONCAT('%',?,'%'),

    if  (`title` LIKE CONCAT('%',?,'%'),
        5,
        3
    ),

    if  (`title` LIKE CONCAT('%',?,'%'),
        2,
        0
    ),
) as pageOrder

FROM Page

WHERE `flags` LIKE CONCAT('%',?,'%') OR `title` LIKE CONCAT('%',?,'%')

ORDER BY pageOrder DESC

SELECT Page.*, 

if  (`flags` LIKE CONCAT('%',?,'%'),

    if  (`title` LIKE CONCAT('%',?,'%'),
        5,
        3
    ),

    if  (`title` LIKE CONCAT('%',?,'%'),
        2,
        0
    ),
) as pageOrder

FROM Page

HAVING pageOrder > 0

ORDER BY pageOrder DESC

使用 mysql 5.7 和 php 7.1

这个的情况下,区别不大。分析一下。

  • 由于没有索引可用于 WHEREORDER BY,因此将扫描整个 table(对于任一公式)。

  • 表达式通常是整个查询的一小部分,所以通常我会忽略LIKEs。但是,在这种情况下,您要为每一行执行 3-4 LIKEs,大约是 WHERE 方法的两倍 LIKEs,因此它可能会稍微慢一些。

  • 有人 可以 认为 WHERE 更具可读性。

  • Page 的所有列,大部分行将被铲入 tmp table。但我认为这两种方法之间没有太大区别。另外,我不一定能找到避免该问题的方法。

这里是一种稍微更紧凑但速度不快的 pageOrder 表达式的表达方式:

  3 * (`flags` LIKE CONCAT('%',?,'%') +
  2 * (`title` LIKE CONCAT('%',?,'%')