sql语句优化原则
2019-03-26 18:05:33 来源:admin 点击:532
查询一条语句,不管连多少表,原则上速度一致,所以切记遇到需要循环的地方,都要批量操作
举例子:
能批量插入的要批量插入,切记不可多次操作数据库,尽量在代码中循环成insert需要的数组,在进行插入
举例子:
foreach ($peopleid as $v){
$peopleid1[] = [
'testid' =>$test_infor,
'uid'=>$v->id
];
}
//先循环,后一次性插入
$test_people = DB::table('表')->insert($peopleid1);批量更新自己的字段,根据其他表或者自己
UPDATE 表名 set allgrade = (systemgrade*0.2+onegrade*0.3+leadgrade*0.5) where testid =139
举例子:
$allLeadGrade = DB::select("UPDATE 表 set leadgrade = c.leadgrade from
(SELECT a.testuid,sum(a.grade) as leadgrade from (SELECT titleid,testuid,avg(peoplegrade) as grade
from test_grade_lead where testid=".$input['testid']." GROUP BY testuid,titleid) as a GROUP BY a.testuid) as c
where uid = c.testuid and testid = ".$input['testid']);
UPDATE 表名 as a set 字段= b.字段 from (select 字段A 语句和表都可以 ) as b where a.字段A = b.字段A
4.任何select结果集都能作为下一个select查询的对象,灵活组合,事半功倍,子查询
举例子:
5.if else语句用好能解决80%的问题,大部分都一样
举例子:postgresql 的 case when 字段 then A else B end
CASE WHEN (SELECT count(*) from parts_index where partsid = t1.id)>0 THEN 1 ELSE (CASE WHEN t1.partstype = 17 THEN 2 WHEN t1.partstype = 24 THEN 3 ELSE 4 END) END as type,
mysql的 select *,if(sva=1,"男","女") as ssva from 表名
6.常用的如果为空
举例子:
1.oracle :
nvl(“字段名”,’转换后的值’);//字段名是双引号,转换后的值是单引号
2.sql Server:
isnull(“字段名”,’转换后的值’)//字段名是双引号,转换后的值是单引号
3.mySql:
ifnull(字段名,’转换后的值’)//字段名不加引号,转换后的值是单引号
注:mySql 也有isnull 但是只判断并不会转换
例子:
oracle
SELECT USERNAME FROM B_USER;
SELECT nvl("USERNAME",'改变后的值') as username FROM B_USER;
sql Server
SELECT ISNULL("USERNAME", '改变后的值') as username FROM B_USER
mySql:
SELECT IFNULL(USERNAME,'改变后的值') as username FROM B_USER;
7.order by 和group by的组合使用(其实原理就是子查询) 这个可以同表操作或者异表操作
select 字段 from 表 as b ,(SELECT uid,SUM(peoplegrade) as grade from test_grade_one where testid = ".$input['testid']." GROUP BY uid) as a where a.uid = b.uid order by 字段
8.链表子查询操作:A表 B表 AB关联表,要查A的列表并且关联B的表数据,或者数据库设计AB关联表时加上常用数据字段,那就能直接查了
SELECT c.id,c.depname,c.desc,d.indname,c.status from A表 as c
LEFT JOIN (select a.depid,a.indid,b.indname from AB关联表 as a LEFT JOIN B表 as b on a.indid = b.id) as d on c.id = d.depid where c."group" = 1
之后循环操作,把id相同的B表字段合并成数组。返回给前端
9.多对多的关系查询
select A.id,A.depname,B.indname from
A inner join AB on A.id=AB.depid
inner join B on B.id = AB.indid
10 当遇到判断的时候,case先走的地方会先执行,后面就不执行了。或者用between 。。and,。。
select (case when yuwen>=80 then '优秀' when yuwen>=60 then '及格' else '不及格' end) as 语文,(case when shuxue>=80 then '优秀' when shuxue>=60 then '及格' else '不及格' end) as 数学,(case when yingyu>=80 then '优秀' when yingyu>=60 then '及格' else '不及格' end) as 英语 from classestest;
11遇到不能需要循环查询的sql,还有一种土办法可以加速
比如上一条统计语句,避免循环,先全部查出来,在双重循环两次结果,得到自己想要的值
foreach ($data as $v){
foreach ($zfxname as $item=>$value){
if($v->name == $item){
$data1[]=[
'name'=>$value,
'count'=>$v->count
];
}
}
}*/