我还有来自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秒。
答案 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
是名称等的首选)。
但是首先,您如何连接以及表的定义是什么?