一个表结构如下:CREATE TABLE Testtemp (
firstname varchar (15) null,
lastname varchar (15) null,
sex char (1) null,
csrq datetime NULL ,
sfzh varchar (18) NULL)
解释:姓名有firstname和lastname组成(sql server为例,oracle修改一下即可)
有如下两个查询语句为了完成查询名字以'李明'开头的所有人:
1,
select * from testadv where ((firstname+lastname) like '李明%') or(firstname is null and lastname like '李明')
2,select * from testadv where (firstname='李' and lastname like '明%') or (firstname like '李明%') or (firstname is null and lastname like '李明%')请问上面两个sql语句是否需要优化?更重要的是上面两个哪个效率比较高?或者谁有更好的办法?(oracle修改上面的‘+’为‘||’即可)
firstname varchar (15) null,
lastname varchar (15) null,
sex char (1) null,
csrq datetime NULL ,
sfzh varchar (18) NULL)
解释:姓名有firstname和lastname组成(sql server为例,oracle修改一下即可)
有如下两个查询语句为了完成查询名字以'李明'开头的所有人:
1,
select * from testadv where ((firstname+lastname) like '李明%') or(firstname is null and lastname like '李明')
2,select * from testadv where (firstname='李' and lastname like '明%') or (firstname like '李明%') or (firstname is null and lastname like '李明%')请问上面两个sql语句是否需要优化?更重要的是上面两个哪个效率比较高?或者谁有更好的办法?(oracle修改上面的‘+’为‘||’即可)
CREATE TABLE Testtemp (
firstname varchar (15) null,
lastname varchar (15) null,
sex char (1) null,
csrq datetime NULL ,
sfzh varchar (18) NULL)
应该为
CREATE TABLE testadv(
firstname varchar (15) null,
lastname varchar (15) null,
sex char (1) null,
csrq datetime NULL ,
sfzh varchar (18) NULL)
我也以为不可以
试了一下,没问题14:14:39 SQL> select * from tcc;AAA BBB
---------- ----------
abc
abc
abc
abc abc
% /实际:200
14:14:47 SQL> insert into tcc values(null,'aaa');已创建 1 行。实际:400
14:15:14 SQL> select * from tcc where aaa||bbb like 'aa%';AAA BBB
---------- ----------
aaa实际:170
14:15:32 SQL>
2, ||运行操作符的操作数可以是null,结果为其余的操作数代表的字符串.
若||的所有的操作数都为 null, 结果为null
3, 即使在(firstname||lastname)上建立index,oracle 的优化器也不会用到它.
因为 where中是 “like”操作符.
where colname like 'XXX%'这种情况则不使用
where colname like '%XXX'不知道老兄在哪儿看到的资料,
我实在网上的某篇文章里面看的
create index ind_testadv_firstname on testadv(substr(firstname,1,2));
create index ind_testadv_firstname on testadv(substr(lastname,1,2));analyze table testadv compute statistics;
analyze index ind_testadv_firstname compute statistics;
analyze index ind_testadv_lastname compute statistics;select * from testadv where substr(firstname,1,2) ='李明' or
substr(lastname,1,2) = '李明';
null值参与||,只要有非空值,是不会得null的
此外如果where中用了is null则用不了索引了,因为索引中不记录键值全为null的列
substr(firstname,1,2) ='李明' or substr(lastname,1,2) = '李明';原因:
1, substr是内置字符函数,取前面字串速度较快.
2, 利用or操作符, 当前面结果为true,不再计算后面条件.
3, '='操作,避免模糊查询.4, 以后若还需调速,可如前述建基于函数的索引(fuction-based index)
你的方法很好,我这里只是举个特例而已,因为中国人的名字还是比较复杂的,这里first和lastname组合起来才是这个人的完全名字,那么当查询者,输入一个'李明',然后按照模糊查询,那么应该列出所有以李明开头的,并且fistname和lastname加起来含'李明'的所有人,用户也可能输入'%李明'等等...而这里就是想通过一个sql语句搞定,所以必须模糊。实在是比较麻烦。
fistname like '李%'
但如果这样就不可以了
fistname like '%李'
就用不了索引,而是全表扫描。
若不建索引,仍然用
substr(firstname,1,2) ='李明' or substr(lastname,1,2) = '李明';原因:
1, substr是内置字符函数,取前面字串速度较快.
2, 利用or操作符, 当前面结果为true,不再计算后面条件.
3, '='操作,避免模糊查询.4, 以后若还需调速,可如前述建基于函数的索引(fuction-based index)
查询速度主要根据index来得额。
如果你index(firstname ,lastname),这种sql比较快点:
select * from table where firstname ='firstname' and lastname like 'lastname%';
如果你index(firstname||lastname),这种sql比较快:
select * from table where firstname||lastname like 'name%';