我的OpenCart
表格排序是utf8_bin
,遗憾的是我无法搜索名称中带有重音的产品名称。我在Google上进行了搜索,发现校对必须为utf8_general_ci
,以便对重音符号和不区分大小写的搜索进行搜索。
如果我在搜索查询中添加整理声明怎么办?
SELECT *
FROM `address`
COLLATE utf8_general_ci
LIMIT 0 , 30
是否有任何(不良)副作用?我是关于索引,性能的问题?还是完全安全?
答案 0 :(得分:3)
我担心你必须考虑查询性能的副作用,特别是那些使用索引的人。这是一个简单的测试:
mysql> create table aaa (a1 varchar(100) collate latin1_general_ci, tot int);
insert into aaa values('test1',3) , ('test2',4), ('test5',5);
mysql> create index aindex on aaa (a1);
Query OK, 0 rows affected (0.59 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc aaa;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| a1 | varchar(100) | YES | MUL | NULL | |
| tot | int(11) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.53 sec)
mysql> explain select * from aaa where a1='test1' ;
+----+-------------+-------+------+---------------+--------+---------+-------+--
----+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | r
ows | Extra |
+----+-------------+-------+------+---------------+--------+---------+-------+--
----+-----------------------+
| 1 | SIMPLE | aaa | ref | aindex | aindex | 103 | const |
1 | Using index condition |
+----+-------------+-------+------+---------------+--------+---------+-------+--
----+-----------------------+
1 row in set (0.13 sec)
mysql> explain select * from aaa where a1='test1' collate utf8_general_ci;
+----+-------------+-------+------+---------------+------+---------+------+-----
-+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows
| Extra |
+----+-------------+-------+------+---------------+------+---------+------+-----
-+-------------+
| 1 | SIMPLE | aaa | ALL | NULL | NULL | NULL | NULL | 3
| Using where |
+----+-------------+-------+------+---------------+------+---------+------+-----
-+-------------+
1 row in set (0.06 sec)
你可以看到MySQL在使用另一个排序规则进行搜索时停止使用a1上的索引,这对你来说可能是个大问题。
要确保将索引用于查询,可能必须将列排序规则更改为最常用的列。
答案 1 :(得分:1)
在using of COLLATE in SQL statements中,我找不到这种用法,无论如何,为了解释使用归类的影响的主要问题,我找到了一些提示,但首先是:
来自 dev.mysql.com :
非二进制字符串(存储在
CHAR
,VARCHAR
和TEXT
数据类型中)具有字符集和排序规则。给定的字符集可以有多个排序规则,每个排序规则为集合中的字符定义特定排序和比较顺序。
对于多个操作数,可能存在歧义。例如:
SELECT x FROM T WHERE x = 'Y';
比较是否应使用列x
或字符串文字'Y'
的排序规则? x
和'Y'
都有排序规则,因此整理排序优先吗?
标准SQL使用以前称为“强制性”规则的方法解决此类问题。 [3]
ORDER BY
- [也在WHERE
]中 - 不能使用任何INDEX
;因此它可能会出乎意料地效率低下。 [4] utf8_general_ci
执行速度慢
但是,如果强制使用不同字符集定义的排序规则,则MySQL必须对列的值进行转码(这会对性能产生影响)。 [5] < / LI>
醇>
答案 2 :(得分:0)
如果可行,请更改列定义。
ALTER TABLE tbl
MODIFY col VARCHAR(...) COLLATE utf8_general_ci ...;
(您应该包含列定义中已有的任何其他内容。)如果要修改多个列,请在同一个ALTER(速度)中执行所有操作。
如果出于某种原因,您无法执行ALTER
,那么,是的,您可以调整SELECT
来更改排序规则:
您提到的SELECT
没有用于过滤的WHERE
子句,所以让我更改测试用例:
假设你有这个,只能找到'圣何塞':
SELECT *
FROM tbl
WHERE city = 'San Jose'
包括San José
:
SELECT *
FROM tbl
WHERE city COLLATE utf8_general_ci = 'San Jose'
如果你可能有“组合口音”,请考虑使用utf8_unicode_ci。 More on Combining Diacriticals和More on your topic。
副作用?除了可能很大的一个:无法使用列上的索引。在我的第二个SELECT
(上图)中,INDEX(city)
没用。 ALTER
SELECT
避免了ALTER
的性能损失,但一次性touchesMoved
本身就很昂贵。
答案 3 :(得分:0)
这可能有所帮助:UTF-8: General? Bin? Unicode?
请注意,utf8_bin
也区分大小写。因此,我会将表格整理改为utf8_general_ci
,并为将来安心。