正文
user
where
userId like
'%123'
;
正例:
select
userId
,
name
from
user
where
userId like
'123%'
;
理由:
6、使用where条件限定要查询的数据,避免返回多余的行。
假设业务场景是这样:查询某个用户是否是会员。曾经看过老的实现代码是这样。。。
反例:
List
<
Long
>
userIds
=
sqlMap
.
queryList
(
"select userId from user where isVip=1"
);
boolean isVip = userIds.contains ( userId );
正例:
Long
userId
=
sqlMap
.
queryObject
(
"select userId from user where userId= 'userId' and isVip='1' "
)
boolean isVip = userId!=null;
理由:
需要什么数据,就去查什么数据,避免返回不必要的数据,节省开销。
业务需求:查询最近七天内登陆过的用户(假设loginTime加了索引)
反例:
select
userId
,
loginTime
from
loginuser
where
Date_ADD
(
loginTime
,
Interval
7
DAY
)
>=
now
();
正例:
explain
select
userId
,
loginTime
from
loginuser
where
loginTime
>=
Date_ADD
(
NOW
(),
INTERVAL
-
7
DAY
);
理由:
8、应尽量避免在where子句中对字段进行表达式操作,这将导致系统放弃使用索引而进行全表扫。
反例:
select
*
from
user
where
age
-
1
=
10
;
正例:
select
*
from
tab1 t1 left join tab2 t2 on t1
.
size
=
t2
.
size
where
t1
.
id
>
2
;
select
*
from
user
where
age
=
11
;
理由:
虽然age加了索引,但是因为对它进行运算,索引直接迷路了。。。
9、Inner join 、left join、right join,优先使用Inner join,如果是left join,左边表结果尽量小。
-
Inner join 内连接,在两张表进行连接查询时,只保留两张表中完全匹配的结果集;
-
left join 在两张表进行连接查询时,会返回左表所有的行,即使在右表中没有匹配的记录;
-
right join 在两张表进行连接查询时,会返回右表所有的行,即使在左表中没有匹配的记录。
都满足SQL需求的前提下,推荐优先使用Inner join(内连接),如果要使用left join,左边表数据结果尽量小,如果有条件的尽量放到左边处理。
反例:
select
*
from
tab1 t1 left join tab2 t2 on t1
.
size
=
t2
.
size
where
t1
.
id
>
2
;
正例:
select
*
from
(
select
*
from
tab1
where
id
>
2
)
t1 left join tab2 t2 on t1
.
size
=
t2
.
size
;
理由:
10、应尽量避免在where子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
反例: