sql场景记忆

1.常见的ddl,dql,dml联合场景

ddl:对于表结构的管理sql语句
dql:常见的sql查询语句
dml:常见的修改数据的update,insert,delete语句

  1. 将一个表里面的数据插入到另外一个表中的纯sql操作,一般可用于建立临时表使得大表变小表
insert into tbl_quick_msg_group 
  (wechatapp_id,user_id,group_name,default_type,update_time,create_time) 
  (select wechatapp_id,user_id,'未分组' group_name,1 default_type,update_time,create_time from tbl_quick_reply group by user_id,wechatapp_id ORDER BY wechatapp_id);

  1. php配合sql的大表瘦身
public function summary()
    {
        $sql="DROP TEMPORARY TABLE IF EXISTS tmp_staff_group_info";
        LogicUtil::db_run_update($sql);
        $sql="DROP TEMPORARY TABLE IF EXISTS tmp_staff_group_rel";
        LogicUtil::db_run_update($sql);

        $sql="CREATE TEMPORARY TABLE tmp_staff_group_info
              SELECT sgi._id, s.user_id
              FROM tbl_staff_group_info sgi
              INNER JOIN tbl_staff_group_rel sgr ON sgr.group_id = sgi._id 
              where sgi.group_name LIKE '%白三涉水%' ";
        LogicUtil::db_run_update($sql);

        $sql="CREATE TEMPORARY TABLE tmp_staff_group_rel
              SELECT b._id, a.user_id
              FROM tbl_staff_wechatapp_relation AS a
              LEFT JOIN tbl_wechatapp AS b ON a.wechatapp_id = b._id
              WHERE b.user_id > 0 && b.app_name LIKE '%白三涉水%' ";
        LogicUtil::db_run_update($sql);


        $sql="  select s.*, 0 group_id 
                from tbl_staff s 
                inner join tmp_staff_group_info A on A._id = s.user_id
                inner join tmp_staff_group_rel B on B._id = s.user_id
                where s.parent_user_id = 16695397
                ORDER BY s.user_id ASC  LIMIT 0, 20";
        $result = LogicUtil::db_run_sql($sql);

        $sql="DROP TEMPORARY TABLE IF EXISTS tmp_staff_group_info";
        LogicUtil::db_run_update($sql);
        $sql="DROP TEMPORARY TABLE IF EXISTS tmp_staff_group_rel";
        LogicUtil::db_run_update($sql);
      
        return $result;
    }

2.1. mysql的索引优化选择器未必绝对可信,我发现以下2条sql,指定索引执行的效率比mysql索引优化器默认的要快很多,说明不要太依赖优化器,特定场景特事特办(优化器使用order 的 last_chat_time的索引,而我指定where条件中的wechatapp_id索引)

 select * from tbl_customer  where wechatapp_id in (11739) && kefu_user_id in(798268289) ORDER BY last_chat_time desc limit 0,10;   /执行30多秒

 select * from tbl_customer FORCE INDEX(`wechatapp_id`) where wechatapp_id in (11739) && kefu_user_id in(798268289) ORDER BY last_chat_time desc limit 0,10;  //执行0.4

  1. 游标场景,缺点内存开销大,容易锁,是一个存储过程
BEGIN  

--定义变量  
declare testrangeid BIGINT;  
declare versionid BIGINT;   
declare done int;  
--创建游标,并存储数据  
declare cur_test CURSOR for   
   select id as testrangeid,version_id as versionid from tp_testrange;  
--游标中的内容执行完后将done设置为1  
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;   
--打开游标  
open cur_test;  
--执行循环  
  posLoop:LOOP  
--判断是否结束循环  
        IF done=1 THEN    
      LEAVE posLoop;  
    END IF;   
--取游标中的值  
    FETCH  cur_test into testrangeid,versionid;  
--执行更新操作  
    update tp_data_execute set version_id=versionid where testrange_id = testrangeid;  
  END LOOP posLoop;  
--释放游标  
CLOSE cur_test; 
  1. sql执行顺序分析:参考文献
    第一步:加载from子句的前两个表计算笛卡尔积,生成虚拟表vt1;
    第二步:筛选关联表符合on表达式的数据,保留主表,生成虚拟表vt2;
    第三步:如果使用的是外连接,执行on的时候,会将主表中不符合on条件的数据也加载进来,做为外部行
    第四步:如果from子句中的表数量大于2,则重复第一步到第三步,直至所有的表都加载完毕,更新vt3;
    第五步:执行where表达式,筛选掉不符合条件的数据生成vt4;
    第六步:执行group by子句。group by 子句执行过后,会对子句组合成唯一值并且对每个唯一值只包含一行,生成vt5,。一旦执行group by,后面的所有步骤只能得到vt5中的列(group by的子句包含的列)和聚合函数。
    第七步:执行聚合函数,生成vt6;
    第八步:执行having表达式,筛选vt6中的数据。having是唯一一个在分组后的条件筛选,生成vt7;
    第九步:从vt7中筛选列,生成vt8;
    第十步:执行distinct,对vt8去重,生成vt9。其实执行过group by后就没必要再去执行distinct,因为分组后,每组只会有一条数据,并且每条数据都不相同。
    第十一步:对vt9进行排序,此处返回的不是一个虚拟表,而是一个游标,记录了数据的排序顺序,此处可以使用别名;
    第十二步:执行limit语句,将结果返回给客户端

4.1 sql绑定参数的那些事:
php在pdo那一层是支持prepare去sql预编译的,参数已bindParam()的是形式绑定进去。之前一直以为参数绑定只是为了防止sql注入,现补充2点:

1.1: 预编译参数绑定执行的sql过程是,php先将sql发送到mysql,mysql执行预编译sql(值得注意的是预编译的过程的sql是开发自己写的sql,并不存在来自客户端用户数据参与的,如果预编译的sql都有注入的问题,那也是开发自己的问题),后面绑定参数走的是不同协议参与到编译的sql中执行的,如此自然不怕其sql注入了
1.2 : 多次执行相同的sql(只是绑定参数不同),mysql只会分析一次,生成执行计划一次,编译一次,减少过程自然效率会有优势(但你需要注意,绑定的参数最好不会对执行计划产生很大影响,mysql这个时候使用的是第一次的执行计划,如果因为你绑定参数使得执行效率很差,一般只有数据不均匀会造成,那你就注意了还有绑定的必要不)

//预处理1--操作数据库
$mysqli = new mysqli('localhost','root','mayi1991','mysqldemo');
$mysqli->query('set names utf8');

//创建预编译对象,这条sql就是先取mysql进行编译处理的,
//我们可以理解成 php与mysql先交互通讯一次,这条sql可是你自己写的,再有sql注入那也是醉了。。。
$mysqli_stmt = $mysqli->prepare("insert account (balance,name) values (?,?)");

//绑定参数
$balance = 122;
$name = '小白';

//TODO 走不同协议去与上一步编译好的sql进行绑定执行的,这里的参数值有可能来自客户端的输入,
//哪怕是用于注入sql的参数值,也没用了,因为之前编译好的sql根本不信任它,只会拿它当参数绑定执行,
//不会因为它去破坏sql的语义。。。
$mysqli_stmt->bind_param("ds",$balance,$name);
//执行 返回boolean值
$mysqli_stmt->execute();
  1. 数据库大表统计
select
table_schema as '数据库',
table_name as '表明',
table_rows as '记录数',
truncate(data_length/1024/1024/1024,2) as '数据容量(GB)',
truncate(index_length/1024/1024/1024,2) as '索引容量'
from information_schema.tables
where table_schema ='wechatapp_customer_service'
ORDER BY data_length desc,index_length desc;
image.png
  1. mysql单机储存空间到达极限,删除索引并立即释放空间,再迁移数据后进行索引恢复
ALTER TABLE `wechatapp_customer_service`.`tbl_message202002` 
DROP INDEX `openid`;

OPTIMIZE table tbl_message201906;  //mysql删除数据后并不会立即腾出空间,执行optimize table  可以快速立即释放
  1. mysql表设计之三范式思想 MySQL设计之三范式的理解

1NF:字段不可分,就是每个字段属性设计都应该保持原子性(比如地址里面包含省份市级县城,这里就不具备原子性,因为省份,市级,县是可以拆分的)
2NF:有主键,非主键字段依赖主键; (一个表中所有的属性应该只能更主键具备唯一识别的关系,而不能跟非主键,比如用户表中,id与uid,既然你的uid就是可以定位用户信息的,这个时候就不应该再使用id)
3NF:非主键字段不能相互依赖; (A表明明已经存在B表的主键id属性,现在又在A表中建立了B表的其他属性字段,这就不满足第三范式了,因为我们明明可以通过A表中的B的唯一索引推出来B的所有属性,故不能在A表中建立B的非主键属性)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容