查找MYSQL TEXT类型列

ant*_*ant 16 mysql activerecord ruby-on-rails

我的表/模型有TEXT类型列,当过滤模型本身的记录时,AR where产生正确的SQL并返回正确的结果,这就是我的意思:

MyNamespace::MyValue.where(value: 'Good Quality')
Run Code Online (Sandbox Code Playgroud)

生成这个SQL:

SELECT `my_namespace_my_values`.* 
FROM `my_namespace_my_values` 
WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'
Run Code Online (Sandbox Code Playgroud)

再举一个例子,我MyNamespace::MyValue在同一value列上加入和过滤但是从另一个模型(在模型上有关系my_values).看到这个(查询#2):

OtherModel.joins(:my_values).where(my_values: { value: 'Good Quality' })
Run Code Online (Sandbox Code Playgroud)

这不会产生正确的查询,这会对value列进行过滤,就像它是一个String列而不是Text一样,因此会产生不正确的结果(仅粘贴相关位置):

WHERE my_namespace_my_values`.`value` = 'Good Quality'
Run Code Online (Sandbox Code Playgroud)

现在我可以通过在我的AR中做LIKE来解决这个问题where,这将产生正确的结果,但查询略有不同.这就是我的意思:

OtherModel.joins(:my_values).where('my_values.value LIKE ?, '%Good Quality%')
Run Code Online (Sandbox Code Playgroud)

终于到了我的问题.这是什么以及它是如何为模型的位置生成的(对于文本列类型)?

WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'
Run Code Online (Sandbox Code Playgroud)

也许最重要的问题是使用以下方面的性能差异:

WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'
Run Code Online (Sandbox Code Playgroud)

还有这个 :

(my_namespace_my_values.value LIKE '%Good Quality%')
Run Code Online (Sandbox Code Playgroud)

更重要的是我如何通过连接获取我的查询(查询#2)产生这样的地方:

WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'
Run Code Online (Sandbox Code Playgroud)

Ric*_*mes 5

(部分答案 - 从MySQL方面接近.)

什么会/不会匹配

案例1 :(我不知道额外的反斜杠和引号来自哪里.)

WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'

\"Good Quality\"               -- matches
Good Quality                   -- does not match
The product has Good Quality.  -- does not match
Run Code Online (Sandbox Code Playgroud)

案例2 :( Good Quality在任何地方找到value.)

WHERE my_namespace_my_values.value LIKE '%Good Quality%'

\"Good Quality\"               -- matches
Good Quality                   -- matches
The product has Good Quality.  -- matches
Run Code Online (Sandbox Code Playgroud)

案例3:

WHERE `my_namespace_my_values`.`value` = 'Good Quality'

\"Good Quality\"               -- does not match
Good Quality                   -- matches
The product has Good Quality.  -- does not match
Run Code Online (Sandbox Code Playgroud)

性能:

  • 如果value声明TEXT,所有情况都很慢.
  • 如果value没有编入索引,则一切都很慢.
  • 如果valueVARCHAR(255)(或更小)编入索引,则案例1和案例3更快.它可以快速找到一行,而不是检查所有行.

换句话说:

  • LIKE使用前导通配符(%)很慢.
  • 索引列对性能很重要,但TEXT无法编制索引.