本周SQL优化实战分享

分享一下本周SQL优化的两个场景。
如果能对读者有一定的启发,共同探讨,不胜荣幸。

版本信息:mysql,5.7.19
引擎: innodb


场景1


我们有一张常口表,里面的数据由各种数据源合并而来,所以人员可能有多个手机号其中还包括座机号。这点在这篇文章里也分享过。http://juejin.cn/post/7234355976458518586
现在人员详情页面需展示同手机号的人员列表,同手机号是包含,而非等同关系。

在人员列表里手机号页面有做展示,那么点击跳转人员详情的时候,是可以把手机号通过URL带过来的,但前端说参数过多,不好控制,所以只传递了人员ID参数。

所以后端查询的时候先得通过主键ID把手机号查出来。之所以不一次性通过join带出手机号再关联同手机号人员,是关联与被关联人员手机号都可能存在多个。


select * 还是select 指定字段


原通过主键查询手机号的SQL,是直接用的mybatis生成器自动生成的SQL。

<select id="selectPhoneByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
    select
    phone
    from t_person_info
    where ID = #{id,jdbcType=VARCHAR}
  </select>

Base_Column_List可想而知是全部字段,类似于select *,这本身没什么,但其中有一部份字段长度在几百,全部加起来也算是个大字段,全部提取对效率还是有一定的影响,所以改为select phone 查询手机一个字段。

select
    phone
    from t_person_info
    where ID = #{id,jdbcType=VARCHAR}

更追求极致一点,可以添加一个idphone的覆盖索引,避免回表。

这一点的优化相对比较鸡肋,都在1-2ms之间看不出明显差别,但把limit放大的时候,还是能看出差距。

表数据70万左右。

select * form table limit 10000

select phone form table limit 10000

174ms vs 7ms

确实是聊胜于无。
但是到底是select * 还是select 指定字段,确实还是存在着一些争议。

一般情况下,表字段少,且不存在大字段,用select * 确实能减少许多麻烦,加减字段不用改sql,多个查询子功能可以共用等。
而且,页面查询多是分页,不太可能一下子查询10000条这种情况。

占用内存,不必要的IO,增加网络负担,拒绝覆盖索引,确实也是select *的问题。

我觉得需要根据具体情况,自行判断,没必要太过教条。


全文检索


拿到手机号以后,根据手机号去查询关联人员。
因为是包含关系,所以同事一开始用的是like模糊匹配。

 select p.id, p.id as pid,p.name,p.idcard,p.phone,count( w.EVENT_NO ) AS count 
      from t_person_info p 
      left join t_other w on w.pid = p.ID
        where
            <foreach collection="phones" item="phone" separator="or" open="(" close=")">
                p.phone like concat("%",#{phone},"%")
            </foreach>
         and p.id != #{id}
        group by p.id

这里的!=有可能会导致索引失效,这时候可以在sql去掉,然后在代码中过滤掉当前人员。

因为where条件中有 p.id != #{id},执行计划倒是从从ALL上升到了range。 耗时1.5秒。

将phone加上全文索引。 where 条件改为

match(p.phone) against (#{phones} IN boolean MODE) and p.id != #{id}

每个手机号需要全匹配,所以这里使用布尔模式,
因为手机号有多个,需要做到or,
又因为涉及到座机号,其中带的-可能会被mysql识别为逻辑运算符。

具体参照我写的这篇文章 http://juejin.cn/post/7234355976458518586


布尔模式的逻辑运算符


  1. +
    select * from t_user where match(phone) AGAINST('a +b' in boolean mode)
    其中 + 会被识别成逻辑运算符,而不是将a +b作为一个整体,以下同理。
    'a +b' 指'a'和'b'必须同时出现才满足搜索条件。
  2. -
    select * from t_user where match(phone) AGAINST('0797 -12345' in boolean mode)
    0797 -123450797必须包含,但不包含12345才能满足搜索条件。
    以下查询排除了包含0797-12345的记录。

    注意-前后空格 0797 -12345才表示包含0797 同时不包含12345.
    0797-12345等于0797 - 12345,它并不等于0797 -12345
    有图为证:

  3. > <
    提高/降低该条匹配数据的权重值。不管使用>还是 <,其权重值均大于没使用其中任何一个的。
    select * from t_user where match(phone) AGAINST('0797(>94649 <12345)' in boolean mode)
    表示匹配0797,同时包含94649的列往前排,包含12345的往后排
    select * from t_user where match(phone) AGAINST('a > b' in NATURAL LANGUAGE mode)
  4. ()
    相当于表达式分组,参考上一个例子。
  5. *
    通配符,只能在字符串后面使用
  6. "
    完全匹配,被双引号包起来的单词必须整个被匹配。
    select * from t_user where match(phone) AGAINST('"0797-1789"' in boolean mode)
    "0797-1789"中不可再分。其它包含0797-1234等记录就不再匹配。
  7. 空格表示 or

这里使用6,7来解决上述的两种问题。
如下SQL,与以下4个手机号其中一个全区配的人员都将被筛选出来。

#{phone}参数应为"135****6" "136****9" "1387****2" "0791-123"格式 。

耗时从1.5秒降到了2毫秒。


场景2

还是常口表,列表查询。


排序


每个用户呢会关联一些事件,无需理会什么是事件,反正这张表中的每条记录与事件表形成一对多的关联关系。
事件实时进入。然后再用户列表展示的时候需要根据关联的事件数来进行排序。

实时join关联事件表,耗时4.9秒。
sql执行计划 extra为 Using temporary; Using filesort 产生了临时表和IO文件排序。当然快不起来。

这还是在没有查询条件,以及没有深度分页的情况下。

那么很明显,需要在用户表建一个冗余字段,保存用户所关联的事件数,再对这个字段建立索引。

但这会牺牲一定的实时性。
以及需要定时任务去统计用户的关联事件数。

然后需要跟产品沟通,因为我们的产品是2B的,还需要跟客户进行沟通。

结合我们的业务场景,经过我们的努力沟通,客户认为牺牲适当的实时性,换来页面的响应效率,是值得的。

然后耗时降到了3毫秒。

一旦 where having order by 里的字段是通过max,min,count等计算出来的虚拟字段,那么肯定会产生 Using temporary; Using filesort 临时表和IO文件排序。
要想办法消灭,不管从业务还是技术上。

适当的建立冗余字段,或者宽表。

但阿里巴巴java开发手册,禁止3张表以上的关联,毕竟只是比较理想的状态。

幸福的公司都是 相似 的;不幸的公司我看也有相似不幸。
不外乎难搞的产品,多变的客户,睿(s)智(13)的老板。


深度分页


上面小节同样的sql,首页查询只需耗时2ms,但是到了700000以后,耗时达到了2.6秒。

这就是著名的mysql深度分页的问题。
通过执行计划,可以明显的看出,mysql会将前 700015条数据取出来,然后丢掉前700000条,只取后15条数据。
前面读取的700000条数据是不必要耗时操作。

解决深度分页的方式有几种。 看具体情况,没有通用的办法。


利用覆盖索引


或者叫利用不回表。
这里为了便利,用主键索引id来演示,innodb下,主键索引为聚簇索引,本身就是回表啦,相当于普通索引省掉了回表操作。

如此查询只需200毫秒左右。

但是,这里不合适把需要展示的字段全部建成一个覆盖索引。


利用覆盖索引延迟关联


先通过覆盖索引把id拿到,再把这15条数据去关联一次拿到其它字段不就好了吗?

select p.id ,p.name,p.idcard,p.phone
from t_person_info p
inner join (select id from t_person_info order by EVENTCOUNT desc limit 700000,15) p2 on p.id = p2.id

如此同样只需要200毫秒左右。


其它方式


其它方式,通过记录上次的位置,通过子查询,都只适用于id为自增主键的情况。

不适用我的这个业务场景。

类似于 这样的SQL

select id ,name,idcard,phone,EVENTCOUNT from t_person_info where id <=(select id from t_person_info order by EVENTCOUNT limit 700000, 1) limit 15;

由于历史友商等原因,我们的数据ID有部份是UUID,它是不连续的,且人员关联事件数EVENTCOUNT也不连续,大量的人员集中在某一个数量上,这都使得此种方式不可取。


分页插件


在做列表展示时肯定需要分页,分页就需要查询总数。
分页插件pagehelper默认会生成一个查询总数的方法。

假如mapper查询方法为selectList(),那么查询总数的方法名为selectList_COUNT()。
对应的SQL为SELECT count(0) FROM 原sql

在一些比较比较简单的SQL的时候,分页的SQL还是会进行重写,比较去掉多余的select字段,不必要的排序等。

但当SQL比较复杂的时候,那就是直接在原SQL上包一层select count(0)。

这个时候我们就可以自已去实现这个selectList_COUNT()这个方法,让它执行效率更高的自定义SQL.


完。

苍茫之天涯,乃吾辈之所爱也;浩瀚之程序,亦吾之所爱也,然则何时而爱耶?必曰:先天下之忧而忧,后天下之爱而爱也!
本文转载于网络 如有侵权请联系删除

相关文章

  • php中函数 isset(), empty(), is_null() 的区别[通俗易懂]

    大家好,又见面了,我是全栈君。NULL: 当你在你的脚本中写下这样一行代码$myvariable;//此处你想定义一个变量,但未赋值。会有Notice:Undefinedvariable echo$myvariable+3;//使用这个变量出现:Notice:Undefinedvariable:myvariablein复制如果将其改写成:$myvariable=NULL; echo$myvariable+3;//这样就不会有问题了复制所以得出在你的脚本在使用一个变量时最好赋一个默认值,如果你不想,就可以将NULL赋给变量,表示这个变量已经定义但没有值,属于NULL类型。is_null(): boolis_null(mixed$var)(php.net官方文档的函数定义) 当参数满足下面三种情况时,is_null()将返回TRUE,其它的情况就是FALSE 1、它被赋值为NULL 2、它还没有赋值 3、它未定义,相当于unset(),将一个变量unset()后,不就是没有定义吗 让我们来看一些例子:$myvar=NULL; var_dump(is_null($myvar));//TRUE

  • Impala 3.4 SQL查询之重写(二)

    在上一篇文章中,我们介绍了Impala基本的SQL解析流程。本文我们将跟大家一起看下Impala中的一些SQL重写规则。这里,我们首先回顾下关于Analyzer的几个类的关系图,如下所示:当SQL被解析为特定的StatementBase之后,紧接着会构造一个AnalysisContext对象,这个类可以理解为整个SQL解析过程的封装,包括了:parsing,analyzingandrewriting这几个过程。在AnalysisContext的analyze方法中,我们构造了Analyzer变量,完成了对StatementBase的analyze(在上篇文章中也已经介绍过)。相关函数调用过程如下所示:Frontend.doCreateExecRequest() -AnalysisContext.analyzeAndAuthorize() --AnalysisContext.analyze() ---AnalysisContext.createAnalyzer() ----Analyzer.ctor() -----GlobalState.ctor() ---StatementBase.a

  • libuv源码阅读(21)--uvtee

    #include<stdio.h> #include<fcntl.h> #include<unistd.h> #include<string.h> #include<stdlib.h> #include<uv.h> typedefstruct{ uv_write_treq; uv_buf_tbuf; }write_req_t; uv_loop_t*loop; uv_pipe_tstdin_pipe; uv_pipe_tstdout_pipe; uv_pipe_tfile_pipe; voidalloc_buffer(uv_handle_t*handle,size_tsuggested_size,uv_buf_t*buf){ *buf=uv_buf_init((char*)malloc(suggested_size),suggested_size); } //释放资源 voidfree_write_req(uv_write_t*req){ write_req_t*wr=(write_req_t*)req;

  • 堆叠之DAD冲突处理与故障恢复机制

    配置双主检测后,主交换机在检测链路上发送DAD竞争报文。堆叠分裂后分裂成多部分的堆叠系统互发竞争报文,并将接收到的竞争报文信息与本部分竞争信息做比较,如果本部分竞争胜出,则不做处理,保持Active状态(正常工作状态),正常转发业务报文;如果本部分竞争失败,则关闭除保留端口外的所有业务端口,转入Recovery状态(业务禁用状态),停止转发业务报文DAD竞争规则如下(依次从第一条开始判断,直至找到最优的交换机才停止比较):1、堆叠优先级比较,堆叠优先级高的交换机优先竞争胜出。2、设备MAC地址比较,MAC地址小的交换机优先竞争胜出。3、不支持组建堆叠的设备之间不会检测到双主冲突。堆叠链路故障修复后,分裂成多部分的堆叠系统进行合并。处于Recovery状态的交换机将重新启动,同时将被关闭的业务端口恢复正常,整个堆叠系统恢复。如果在链路故障修复前,承载业务的Active状态的交换机系统也出现了故障。此时,可以先将Active状态的交换机从网络中移除,再通过命令行启用Recovery状态的交换机,接替原来的业务,然后再修复原Active状态交换机的故障及链路故障。故障修复后,重新合并堆叠系统

  • Python常用操作的复杂度

      我们前面讲过list、deque、堆、字典树等高性能计算的技巧,这一节我们来整理一下Python中常用操作的时间复杂度。本文中的N表示容器的元素数量,K表示参数中元素的数量或参数的值。listlst=list(range(10,20)) l1=list(range(100,105)) 复制操作时间复杂度描述lst[2]O(1)访问元素lst.pop()O(1)弹出最后一个值lst.append(l1)O(1)在末尾添加元素lst.extend(l1)O(K)在末尾逐个添加元素lst.clear()O(1)清空listlst.copy()O(N)列表拷贝lst.count(15)O(N)元素计数lst.remove(15)O(N)删除一个元素lst.reverse()O(N)反序lst.sort()O(N*log(N))排序lst.insert(1,200)O(N)在某一位置插入元素dellst[0]O(N)删除某个位置的元素lst.index(15)O(N)查找元素,并返回元素位置bisect.bisect_left(lst,15)O(log(N))有序列表使用bisect查找元素

  • 三分钟读懂Softmax函数

    Softmax是一种激活函数,它可以将一个数值向量归一化为一个概率分布向量,且各个概率之和为1。Softmax可以用来作为神经网络的最后一层,用于多分类问题的输出。Softmax层常常和交叉熵损失函数一起结合使用。从二分类到多分类对于二分类问题,我们可以使用Sigmod函数(又称Logistic函数)。将(-\infty,+\infty)范围内的数值映射成为一个(0,1)区间的数值,一个(0,1)区间的数值恰好可以用来表示概率。g(z)=\frac1{1+e^{-z}} 比如,在互联网广告和推荐系统中,曾广泛使用Sigmod函数来预测某项内容是否有可能被点击。Sigmoid函数输出值越大,说明这项内容被用户点击的可能性越大,越应该将该内容放置到更加醒目的位置。除了二分类,现实世界往往有其他类型的问题。比如我们想识别手写的阿拉伯数字0-9,这就是一个多分类问题,需要从10个数字中选择一个概率最高的作为预测结果。手写体识别数据集mnist对于多分类问题,一种常用的方法是Softmax函数,它可以预测每个类别的概率。对于阿拉伯数字预测问题,选择预测值最高的类别作为结果即可。Softmax的公

  • left join左表一定是驱动表吗?

    leftjoin左表一定是驱动表吗?日常工作中,遇到很多leftjoin的SQL,今天对leftjoin的这种语法进行简单讲解。刚开始接触MySQL的时候,我也认为使用leftjoin的时候,是左表驱动右表的,但是随着对MySQL理解的深入,时间长了发现这个理解是错误的。我们先来看个例子:mysql>createtablea(f1int,f2int,index(f1))engine=innodb; QueryOK,0rowsaffected(0.01sec) mysql>createtableb(f1int,f2int)engine=innodb; QueryOK,0rowsaffected(0.01sec) mysql>insertintoavalues(1,1),(2,2),(3,3),(4,4),(5,5),(6,6); QueryOK,6rowsaffected(0.00sec) Records:6Duplicates:0Warnings:0 mysql>insertintobvalues(3,3),(4,4),(5,5),(6,6),(7,7),

  • Zabbix后端存储ES的优化实践

    场景分析▼由于公司zabbix的历史数据存储在elasticsearch中,有个需求是尽可能地把监控的历史数据存储的长一点,最好是一年,目前的情况是三台ES节点,每天监控历史数据量有5G,目前最多可存储一个月的数据,超过30天的会被定时删除,每台内存分了8G,且全部使用机械硬盘,主分片为5,副本分片为1,查询需求一般只获取一周的历史数据,偶尔会有查一个月到两个月历史数据的需求。节点规划▼为了让ES能存储更长的历史数据,以及考虑到后续监控项添加导致数据的增长,我将节点数量增加至4节点,并将部分节点内存提高,部分节点采用SSD存储优化思路▼对数据mapping重新建模,对str类型的数据不进行分词,采用冷热节点对数据进行存储,前七天数据的索引分片设计为2主1副,索引存储在热节点上,超过七天的数据将被存储在冷节点,超过30天的索引分片设置为2主0副本,ES提供了一个_shrink的api来进行压缩。由于ES是基于Lucene的搜索引擎,Lucene的索引由多个segment组成,每一个段都会消耗文件句柄,内存和CPU运行周期,段数量过多会使资源消耗变大,搜索也会变慢,这里我将前一天的索引分片

  • 老大难的GC原理及调优,这下全说清楚了

    内容主要如下:GC基础原理,涉及调优目标,GC事件分类、JVM内存分配策略、GC日志分析等。CMS原理及调优。G1原理及调优。GC问题排查和解决思路。GC基础原理GC调优目标大多数情况下对Java程序进行GC调优,主要关注两个目标:响应速度(Responsiveness):响应速度指程序或系统对一个请求的响应有多迅速。 比如,用户订单查询响应时间,对响应速度要求很高的系统,较大的停顿时间是不可接受的。调优的重点是在短的时间内快速响应。吞吐量(Throughput):吞吐量关注在一个特定时间段内应用系统的最大工作量。 例如每小时批处理系统能完成的任务数量,在吞吐量方面优化的系统,较长的GC停顿时间也是可以接受的,因为高吞吐量应用更关心的是如何尽可能快地完成整个任务,不考虑快速响应用户请求。GC调优中,GC导致的应用暂停时间影响系统响应速度,GC处理线程的CPU使用率影响系统吞吐量。GC分代收集算法现代的垃圾收集器基本都是采用分代收集算法,其主要思想:将Java的堆内存逻辑上分成两块:新生代、老年代,针对不同存活周期、不同大小的对象采取不同的垃圾回收策略。新生代(YoungGenerati

  • angularjs学习第九天笔记(指令作用域【隔离作用域】研究)

    您好,昨天学习了指令作用域为布尔型的情况,今天主要研究其指针作用域为{}的情况1、当作用域scope为{}时,子作用域完全创建一个独立的作用域,  此时,子做预约和外部作用域完全不数据交互  但是,在实际应用中,子做作用域也还是要和外部数据交互。       为止,引入了数据绑定概念2、隔离作用域数据绑定有三种方式: 其一、“@”    格式为:      scope{        属性名称:"@"      }    子外作用域数据交互表现:隔离的子作用域和外部作用域实现单向数据绑定,      及外部对应值改变,子作用域值也改变,子作用域值改变父作用域值不改变其二、“=”:     格式为:      scope{        属性名称:"@"      }    子外作用域数据交互表现:      隔离的子作用域和外部作用域实现双向数据绑定,      及外部对应值改变,子作用域值也改变,子作用域值改变父作用域值也改变  其三、“&”:     格式为:      scope{        属性名称:"&&q

  • 年度巨献 | 《2016年中国网络空间安全年报》重磅发布!

    日前,由安恒信息风暴中心策划编撰的《2016年中国网络空间安全年报》重磅发布。《2016年中国网络空间安全年报》旨在从安全大数据的视角,围绕“数据决策治理、数据带动思考、数据推动创新”的理念,跨地域、跨系统、跨行业地“数读”中国网络空间安全现状和趋势,为广大读者提供更加量化和全面的网络空间安全立体图景,希望给各级主管部门、各级领导单位网络安全治理参考和启发,为推动我国网络强国建设提供决策支持。 今天,我们特地精选了《2016年中国网络空间安全年报》部分摘要进行预览,并在1月23日-2月5日期间,将通过连载的方式对《2016年中国网络空间安全年报》进行全面报道,欢迎大家关注和阅读!2016网络空间安全态势之重要WEB应用安全分析报告网络安全态势感知是根据网络安全监测数据进行提取、分析,并结合最新安全威胁情报、安全预警,对某个范围/行业整体的安全状态进行分析预测,对于提高网络安全监管单位的监控能力、应急响应能力、预测网络发展趋势有重要的意义。2016年,安恒信息风暴中心持续对全国重点行业(政务、教育、金融、医疗)的405965个重要网站及信息系统做全面的监测与分析,该报告将从基础信息普查

  • 【工业大数据三问】是什么?为什么?怎么办?

  • Kazoo Python Zookeeper 选主

    本文讲述基于zookeeper选主与故障切换的方法。我们的例子使用的是python。使用的库是kazoo,安装方式pipinstallkazoo 复制应用场景:多个实例部署,但不是“去中心化”的部署方式;有且只有一个节点作为master,履行master的职责,在例子中是注册调度器;其他实例作为slave,不提供调度功能,但是在master节点挂掉之后,可以重新进行选主调度。1、注册调度器我们只给出伪代码,简单的打印调度器注册结果。#-*-coding:utf-8-*- #调度器注册和关闭 #模拟主节点的职责 classMyScheduler(object): #注册调度器 definit_scheduler(self): print'##########开启调度器成功############' #关闭调度器 defstop_scheduler(self): print'##########关闭调度器成功############'复制2、选主与故障切换代码1)使用add_listener注册监听器,监听zookeeper会话超时,Sess

  • 基于Python使用SVM识别简单的字符验证码的完整代码开源分享

    关键字:Python,SVM,字符验证码,机器学习,验证码识别1   概述基于Python使用SVM识别简单的验证字符串的完整代码开源分享。因为目前有了更厉害的新技术来解决这类问题了,但是本文作为初级入门方法,还是具有一定的学习意义的,所以就将源码和相关的素材开源出来。本文虽然已经不具备太强的实战性和迁移性,但是主要希望能够是以一个有趣的应用点来让对机器学习有兴趣的同学找到入门点。上面提到的“更厉害的新技术”是指“CNN卷积神经网络”,这个工具基本上免去了本文介绍的繁杂的图片预处理工作,而且通用性更强,换一种验证模式,基本上不需要修改任何代码,就可以训练出想要的模型。但是这部分入门门槛会稍微高一些,后续有机会,会逐渐开一个专题来讲此类高级方法。总之,最后会有一个结论:传统的字符验证码是完全没有防御自动化的能力了。输入图片:输出字符串:69372   详细原理完整的识别的源码项目:https://github.com/zhengwh/captcha-svm复制代码有些丑,但是结合原理文档,应该还算是比较清晰的。关于原理文档请参考博客:《字符型图片验证码识别完整过程及Python实现》ht

  • TitleLayout——一个Android轻松实现通用、标准、支持沉浸式状态栏的标题栏库

    TitleLayout 多功能、通用的、可在布局或者使用Java代码实现标题栏; 支持沉浸式状态栏; 支持左侧返回按钮不需要手动实现页面返回; 支持左侧按钮,中间标题,右边按钮点击 左侧支持图片+文字、单独图片、单独文字;右侧支持单独图片、单独文字等。 图片有点虚,请见谅 堆码不易,star支持,万分感谢 欢迎关注: Github地址:https://github.com/SiberiaDante/TitleLayout 博客园:http://www.cnblogs.com/shen-hua/ email: 994537867@qq.com Android开发必备经典收藏集(整理中) Android开发常备工具整理中 重点说明: 若左侧文字或者按钮为返回键,只需要布局中使用如下代码即可; dante:d_is_back_view="true"复制 或者Java代码中 titleLayout.setIsLeftBackView(true)复制 无须在设置onClickListener,this.finish等;如有特殊需要,可设置属性为false,实现方法:

  • 重新定义 vscode 命令行工具 code命令

    vscode默认命令行有问题 他那个每次都打开cli.js 目录名里面有空格要&开头后面跟双引号 所以从新定义后变量是$变量名前面再加上&就能调用那个exe了 后面再跟上目录就ok了 #echo$PROFILE setcode"C:\Users\Reciter\AppData\Local\Programs\MicrosoftVSCode\Code.exe" #set-aliasd='npmrundev' functiond{npmrundev} functiondc{&$codeC:\Users\Reciter\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1} #打包发布到远程 functionpp{npmrunbuildAndPublic} functionvuejs{&$codeE:\root\Personal\giteez\vuejsdev-com} functionnote{&$codeC:\project\mdNote} functionnavi{&

  • 016 Python 中的基本运算符

    #!/usr/bin/envpython #-*-coding:utf-8-*- #Datatime:2022/7/2815:01 #Filename:016Python中的基本运算符.py #Toolby:PyCharm #https://www.cnblogs.com/nickchen121/p/10728299.html #变量 #数据类型 #输入输出 #存不是目的,取才是目的 #现在计算机能认识客观世界的万事万物,但是呢,他还得对客观世界的万事万物作比较(逻辑运算、算术运算) #算术运算符 #+-*/%// a=1 b=2 print(a+b) print(a-b) print(a*b) print(a/b) print(a%b)#取余 print(100//11)#取整 #布尔类型 #True真 #False假 #比较运算符 print(a>b) print(a<b) print(a==b) print(a!=b) #赋值运算符 #= c=3 #+= c+=3#c=c+3 print(c) print('*'*100) #逻辑运算符 #A

  • WPF的xaml中特殊字符表示 转自https://www.cnblogs.com/Laggage/p/10425423.html

    WPF的xaml中特殊字符表示 转自https://www.cnblogs.com/Laggage/p/10425423.html   直接看表,描述很清晰 字符 转义字符 备注 &(ampersand) &amp; 这个没什么特别的,几乎所有的地方都需要使用转义字符 >(greater-thancharacter) &gt; 在属性(Attributevalues)中必须进行转义,在内容(Content)中 如果没有<在>符号的前面,可以不进行转义,直接使用> <(less-thancharacter) &lt; 在属性(Attributevalues)中必须进行转义,在内容(Content)中 如果没有>在<符号的后面,可以不进行转义,直接使用< "(straightquotationmark) &quot; 在属性(AttributeValues)中必须进行转义,在内容(Content)中

  • oracle on suse 连接 mysql

    参考文档 https://www.sohu.com/a/339295793_784849 https://www.cnblogs.com/rangle/p/8967643.html oracleonsuse连接mysqlby黄良谋实测成功 一,安装unixODBC 下面两个文件传到 /usr/local/下  sshroot登陆 cd/usr/local/ 1,下载unixODBC最新版本:http://www.unixodbc.org/ ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.9.tar.gz  2,tarzxvfunixODBC-2.3.9.tar.gz 3,cdunixODBC-2.3.9 4,#./configure--prefix=/usr/local/unixODBC-2.3.9--includedir=/usr/include--libdir=/usr/lib-bindir=/usr/bin--sysconfdir=/etc 安装成功后,unixODBC所需的头文

  • Springboot进阶-01

    Springboot进阶-JDBC、Druid、Mybatis、Swagger、SpringMVC、Mail 1.Springboot-JDBC Springboot整合JDBC后,引入spring-boot-starter-jdbc,通过JdbcTemplate来操作数据库。 导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> 复制 通过JdbcTemplate来操作数据库,进行增删改查 @RestController publicclassUserController{ @Resource privateJdbcTemplatejdbcTemplate; @GetMapping("/delete") publicStringdelete(){ Stringsql="deletefromtb_us

  • prometheus监控mongo

    之前环境已经安装过相应环境,我们之间从插件开始安装 参考 :https://github.com/percona/mongodb_exporter            https://github.com/dcu/mongodb_exporter            https://github.com/Masterminds/glide/     使用的插件是:https://github.com/dcu/mongodb_exporter 使用的展示json是:https://grafana.com/dashboards/2583 需要先安装glide工具:参考地址https://studygolang.com/articles/10804 gogetgithub.com/Masterminds/glidegoinstallgithu

相关推荐

推荐阅读