【问题标题】:slow mysql query with Like / match against使用 Like / match 的慢 mysql 查询
【发布时间】:2012-06-20 23:11:33
【问题描述】:

我需要搜索比实际更大的最接近的拨号代码。例如,最接近 33 的将是 331 或 332(如果 331 不存在)...所以它必须是 33xxxx,34 无效。

这 2 个查询有效,但速度太慢(250 毫秒/行):

SELECT Dialcode
FROM table
WHERE (Dialcode LIKE '$var%' AND Dialcode > '$var' AND Price IS NOT NULL)
ORDER BY Dialcode ASC LIMIT 1

SELECT Dialcode
FROM table
WHERE (MATCH(Dialcode) AGAINST ('$var*' IN BOOLEAN MODE) AND Dialcode > '$var'
      AND Price IS NOT NULL)
ORDER BY Dialcode ASC LIMIT 1

我的拨号代码是 PRIMARY KEY BIGINT(15)。

我是这样做的吗,它真的很快(>1ms/行),但这并不是我所需要的:

SELECT Dialcode
FROM table
WHERE (Dialcode >= '$var' AND Price IS NOT NULL)
ORDER BY Dialcode ASC LIMIT 1

所以我想我的问题是 LIKE / MATCH AGAINST。

任何想法都将不胜感激。

更新解决方案:

改编自raina77ow建议的解决方案:

SELECT Dialcode FROM table WHERE (( (Dialcode BETWEEN $var * 1 AND ’9’ )
   OR (Dialcode BETWEEN $var * 10 AND $var.’99’ )   
   OR (Dialcode BETWEEN $var * 100 AND $var.’999’ )
OR (Dialcode BETWEEN $var * 1000 AND $var.’9999’ )
…
) AND Price IS NOT NULL) ORDER BY Dialcode ASC LIMIT 1

谢谢大家!

【问题讨论】:

  • Hm LIKE 需要转换为字符串/字符,这可能需要一段时间。您可以在表格的副本上测试该理论:将列转换为 char,然后看看效果如何。
  • 是的,我更喜欢将列转换为字符,然后在其上构建另一个索引;那么简单的 LIKE CONCAT(value + '%') 会创造奇迹,我想,因为它应该达到索引。

标签: mysql sql-like match-against


【解决方案1】:

我看到这里的主要问题是索引是建立在 Dialcode 的数值之上的,而不是字符串。所以这两个查询根本不使用索引。

你可以尝试构建一个数值函数,问题是这个函数在评估的左边部分会有 Dialcode - 所以索引不会再次被使用。

也许这种方法可能更有用。

SELECT Dialcode 
FROM table 
WHERE ( (Dialcode BETWEEN %value% * 10 AND (%value%*10 + 9) 
   OR (Dialcode BETWEEN %value% * 100 AND (%value%*100 + 99) 
   OR (Dialcode BETWEEN %value% * 1000 AND (%value%*1000 + 999)
   ...
) AND Price IS NOT NULL
ORDER BY Dialcode LIMIT 1;

它丑得要命(我什至前两次都写错了 - alfasin 应该得到纠正我的功劳),是的,但它应该达到索引。另一种方法是使用 UNION(而不是 OR),但我想这两个查询将以相同的方式执行(虽然它没有经过验证)。

【讨论】:

  • 您可能的意思是:AND %value% * 10 +9 而不是 AND %value% * 11 - 1 等。我喜欢您的解决方案(+1)
  • 谢谢,你的数学比我的好。 )
  • 是的!这就是要走的路!我对其进行了一些修改,因为在这种情况下 34 将匹配,并且它应该严格以 33 开头...(例如)
【解决方案2】:

尝试使用正则表达式,例如:

SELECT Dialcode
FROM table
WHERE Dialcode REGEXP '^[$var]'
ORDER BY Dialcode ASC LIMIT 1

我现在无法测试它,但我相信它应该可以工作。

【讨论】:

  • 而 LIKE 不是 using regex?
  • @raina77ow 你可能想问 regex 是否没有使用 LIKE 这是一个很好的问题,我想这取决于实现。在比较数字时,我希望答案是“否”,但老实说我不知道​​。易于测试并找出查询的运行时间;)
  • 我测试过,它更快,但不如 BEETWEEN 选项。
猜你喜欢
  • 2017-11-25
  • 1970-01-01
  • 2020-04-23
  • 2020-03-21
  • 2021-09-04
  • 1970-01-01
  • 2016-08-12
  • 1970-01-01
相关资源
最近更新 更多