col LIKE BINARY'val%'比col LIKE'val%'慢得多。为什么?

时间:2019-04-17 10:07:36

标签: mysql database collation database-indexes

我还有来自this question的后续跟踪。尽管LIKE模式搜索(由于排序规则集)使用索引并且比LIKE BINARY快得多,但是对这两个查询进行解释似乎都表明两个查询都使用了索引。

explain select count(*) from TransactionApp_transactions where merchantId like 'VCARD000%'

| id | select_type | table                       | type  | possible_keys                        | key                                 | key_len | ref  | rows     | Extra                    |
+----+-------------+-----------------------------+-------+--------------------------------------+--------------------------------------+---------+------+----------+--------------------------+
|  1 | SIMPLE      | TransactionApp_transactions | range | TransactionApp_transactions_fc3e7169 | TransactionApp_transactions_fc3e7169 | 767     | NULL | 12906834 | Using where; Using index |

我得到与EXPLAIN完全相同的explain select count(*) from TransactionApp_transactions where merchantId like binary 'VCARD000%';输出(其中rows是一个较小的数字)

key列包含两个EXPLAIN输出的索引名称,但是LIKE BINARY花费26秒,而简单的LIKE仅花费2秒。

2 个答案:

答案 0 :(得分:1)

在给定WHERE column LIKE 'value%'的索引的情况下,使用WHERE column LIKE BINARY 'value%'的查询比使用column的查询要快得多。这是完全可以预期的。为什么?

LIKE 'value%'过滤器使用索引查找匹配的行。假设要匹配的'value%'文本使用与列相同的排序规则。并且,索引使用它们索引的列的排序规则;整理归入索引。在该列包含不区分大小写的文本的情况下,即使必须忽略大小写,这也使得搜索'value%''Value%''VALUE%'都可以使用索引。搜索。

使用LIKE BINARY而不是LIKE时,您需要声明搜索所需的排序规则。您告诉MySQL的查询计划者它不能使用它拥有的索引,因为该索引的内置排序规则对查询没有用。因此,它会进行全表扫描。太慢了。

如果要区分大小写的搜索,请在创建(或更改)表时为该列声明区分大小写的排序规则。然后,LIKE过滤器将区分大小写。

要获得区分大小写的排序规则,您可以创建类似以下的表(您没有显示表定义,所以这是一个猜测)。

  CREATE TABLE tbl (
     ...
     mid VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_bin,
     ...
  )

或者您也可以像这样更改列以区分大小写。

 ALTER TABLE tbl MODIFY mid VARCHAR(255) COLLATE latin1_bin;

备注:WHERE col LIKE BINARY 'value%'是一种写查询的奇怪方法。这可能就是为什么EXPLAIN不能很好地完成它的原因。

答案 1 :(得分:0)

对所有这些使用相同归类:

  • 连接到数据库
  • 客户端中的
  • 个字节
  • 正在测试的列。

merchantId可能是(或应该是)CHARACTER SET ascii。这可能与其他字符串不符(utf8mb4是名称等的首选)。

但是首先,您如何连接以及表的定义是什么?