LIKE语句的语法格式是:select*from表名where字段名like对应值(子串),它主要是针对字符型字段的,它的作用是在一个字符型字段列中检索包含对应子串的。假设有一个数据库中有个表table1,在table1中有两个字段,分别是name和sex二者全是字符型数据。现在我们要在姓名**中查询以“张”字开头的记录,语句如下:select*fromtable1wherenamelike"张*"如果要查询以“张”结尾的记录,则语句如下:select*fromtable1wherenamelike"*张"这里用到了通配符“*”,可以说,like语句是和通配符分不开的。下面我们就详细介绍一下通配符。多个字符*c*c代表cc,cBc,cbc,cabdfec等它同于DOS命令中的通配符,代表多个字符。多个字符%%c%代表agdcagd等这种方法在很多程序中要用到,主要是查询包含子串的。特殊字符aa代表a*a代替*单字符?b?b代表brb,bFb等同于DOS命令中的?通配符,代表单个字符单数字#k#k代表k1k,k8k,k0k大致同上,不同的是代只能代表单个数字。字符范围-[a-z]代表a到z的26个字母中任意一个指定一个范围中任意一个续上排除[!字符][!a-z]代表9,0,%,*等它只代表单个字符数字排除[!数字][!0-9]代表A,b,C,d等同上组合类型字符[范围类型]字符cc[!a-d]#代表ccF#等可以和其它几种方式组合使用例:假设表table1中有以下记录:namesex张小明男李明天男李a天女王5五男王清五男下面我们来举例说明一下:查询name字段中包含有“明”字的。select*fromtable1wherenamelike'%明%'查询name字段中以“李”字开头。select*fromtable1wherenamelike'李*'查询name字段中含有数字的。select*fromtable1wherenamelike'%[0-9]%'查询name字段中含有小写字母的。select*fromtable1wherenamelike'%[a-z]%'查询name字段中不含有数字的。select*fromtable1wherenamelike'%[!0-9]%'我们着重要说明的是通配符“*”与“%”的区别。select*fromtable1wherenamelike'*明*'select*fromtable1wherenamelike'%明%'大家会看到,前一条语句列出来的是所有的记录,而后一条记录列出来的是name字段中含有“明”的记录,所以说,当我们作字符型字段包含一个子串的查询时最好采用“%”而不用“*”,用“*”的时候只在开头或者只在结尾时,而不能两端全由“*”代替任意字符的情况下。大家在写sql语句的时候,如果是select..where类型的语句,有注意到条件的前后顺序吗?我今天做个小实验。比如查询地址里包含“海口市”及“振兴路”两个关键字的数据,一般时候可能会用select*fromdm_addrwhereaddrlike'%海口市%'andaddrlike'%振兴路%'的形式,但其实这种查询效率不高,原因在于条件的前后顺序。以下是测试结果mysql>selectcount(1)fromdm_addrwhereaddrlike'%振兴路%'andaddrlike'%海口市%';+----------+|count(1)|+----------+|96|+----------+1rowinset(0.82sec)mysql>selectcount(1)fromdm_addrwhereaddrlike'%海口市%'andaddrlike'%振兴路%';+----------+|count(1)|+----------+|96|+----------+1rowinset(0.91sec)我做了很多次查询whereaddrlike'%海口市%'andaddrlike'%振兴路%'总是比whereaddrlike'%振兴路%'andaddrlike'%海口市%'慢,原因是查询是先处理第一条件,然后在处理第二个条件,先查询出所有包含“海口市”的记录,再在这些记录中查询包含"振兴路"的记录。对于地址情况,包含“海口市”的记录可能大于"振兴路"的记录,我做测试的表有2万条数据,已经有大概0.1s的差别。如果碰到大数据,这个差别会更大。按以上的分析结果,我们写SQL语句的时候,对于select...where...类型的语句,应该把查询结果范围小的条件放在前面,查询范围大的条件放在后面,这样会提高效率。对于OR的情况:测试如下:mysql>selectcount(1)fromdm_addrwhereaddrlike'%海口市%'oraddrlike'%振兴路%';+----------+|count(1)|
+----------+
| 39168 |
+----------+
1 row in set (0.84 sec)
mysql> select count(1) from dm_addr where addr like '%振兴路%' or addr like '%海
口市%';
+----------+
| count(1) |
+----------+
| 39168 |
+----------+
1 row in set (0.95 sec)
OR 语句的处理过程是这样, 对于每一条地址, 逐个分析条件,如果符合第一个条件,就不
做第二条件的判断,那么我们应该把容易做判断的条件放在前面, 比如查询地址里 包含“海
口市”或“振兴路” 个关键字的数据,按地址一般排法,XX 市应该在XX 路前。所以如果用
第一种方式,那就效率高,判断有海口市就可以确认这行地址有效了。 所以在写OR 类型的
条件时, 应该把容易判断的条件写在前面。大地址写在前,小的写在后边
再做一个NOT ... OR .. NOT ... 测试,查询不包含 海口市 或者不包含 振兴路 的数据
mysql> select count(1) from dm_addr where addr not like '%海口市%' or addr not like
'%振兴路%';
+----------+
| count(1) |
+----------+
| 38752 |
+----------+
1 row in set (0.92 sec)
mysql> select count(1) from dm_addr where addr not like '%振兴路%' or addr not like
'%海口市%';
+----------+
| count(1) |
+----------+
| 38752 |
+----------+
1 row in set (0.86 sec)
因为每条数据都有海口市, 所以对于第一个查询,判断第一个条件都失败了, 都需要判断
第二个。
对于第二个查询, 只要判断第一个条件为真就可以确定这个记录, 不需要判断第一个条件,
所以第二个查询效率高过第一个。
结论:对于select ... where ... 类型的语句。
对于OR 条件, 需要把命中率高的条件放在前面。
对于AND 条件,需要把条件限制范围小的条件放在前面。
希望这些实验能提高 phper 的程序效率。以上测试是对于 mysql 5.0 win 做的。好象记得
ORACLE 刚好相反, 是先判断最后的条件。