应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

MySQL数据库性能优化由浅入深

  简介:通俗地理解三个范式,对于数据库设计大有好处。在数据库设计中,为了更好地应用三个范式,就必须通俗地理解三个范式(通俗地理解是够用的理解,并不是最科学最准确的理解
  文章目录
  0SQL性能分析
  1表的设计合理化
  1。1为什么需要范式
  1。2三范式原理
  1。3什么样的表才满足三范式
  2慢查询
  2。1慢查询介绍
  2。2慢查询步骤
  3添加适当索引
  3。1索引是什么
  3。2索引优劣势
  3。3索引分类和建索引命令语句
  3。4创建索引情况分析
  4Explain分析(重点)
  4。1Explain介绍
  4。2id(表的读取顺序)
  4。3selecttype(数据读取操作的操作类型)
  4。4table(显示执行的表名)
  4。5type(访问类型排列)
  4。6possiblekeys(哪些索引可以使用)
  4。7key(哪些索引被实际使用)
  4。8keylen(消耗的字节数)
  4。9ref(表之间的引用)
  4。10rows(每张表有多少行被优化器查询)
  4。11Extra〔ekstr〕
  4。12练习
  5索引优化
  5。1索引单表优化案例
  5。2索引两表优化案例
  5。3索引三表优化案例
  5。4索引失效案例
  5。5索引面试题分析
  5。6总结
  5。7小表驱动大表
  5。8Orderby优化
  5。9Groupby优化
  6ShowProfile分析(重点)
  7MySQL配置优化
  0SQL性能分析
  SQL性能下降原因:
  1、查询语句写的烂
  2、索引失效(数据变更)
  3、关联查询太多join(设计缺陷或不得已的需求)
  4、服务器调优及各个参数设置(缓冲、线程数等)
  通常SQL调优过程:
  观察,至少跑1天,看看生产的慢SQL情况。
  开启慢查询日志,设置阙值,比如超过5秒钟的就是慢SQL,并将它抓取出来。
  explain慢SQL分析。
  showprofile。
  运维经理orDBA,进行SQL数据库服务器的参数调优。
  总结:
  1、慢查询的开启并捕获
  2、explain慢SQL分析(没索引的先建索引)
  3、showprofile查询SQL在Mysql服务器里面的执行细节和生命周期情况
  4、SQL数据库服务器的参数调优
  数据库的分类
  关系型数据库:mysqoracledb2informixsysbasesqlserver
  非关系型数据库:(特点:面向对象或者集合)
  NoSql数据库:MongoDB(特点是面向文档)
  1表的设计合理化
  1。1为什么需要范式
  一个软件项目基本都会用到数据库,项目开发前期分析客户的业务和数据处理需求,然后设计数据库的ER模型图,确认需求信息的正确和完整。再就要将ER图转换为多张表,表设计后,很可能结构不合理,出现数据重复保存,简称数据的冗余,这对数据的增删改查带来很多后患,所以我们需要审核是否合理,就像施工图设计后,还需要其他机构进行审核图纸是否设计合理一样。
  如何审核呢?需要一些有关数据库设计的理论指导规则,这些规则业界简称数据库的范式。数据库范式为数据库的设计、开发提供了一个可参考的典范。
  1。2三范式原理
  通俗地理解三个范式,对于数据库设计大有好处。在数据库设计中,为了更好地应用三个范式,就必须通俗地理解三个范式(通俗地理解是够用的理解,并不是最科学最准确的理解
  第一范式:1NF是对属性的原子性约束,要求属性(列)具有原子性,不可再分解;(只要是关系型数据库都满足1NF)
  第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;
  第三范式:3NF是对字段冗余性的约束,它要求字段没有冗余。没有冗余的数据库设计可以做到。
  但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。
  1。3什么样的表才满足三范式
  表的范式,是首先符合1NF,才能满足2NF,进一步满足3NF
  1NF:即表的列的具有原子性,不可再分解,即列的信息,不能分解,只有数据库是关系型数据库
  2NF:表中的记录是唯一的,就满足2NF,通常我们设计一个主键来实现
  3NF:即表中不要有冗余数据,就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放
  反3NF:在表1n的情况下,为了提高效率可能会在1这张表设计字段提速
  2慢查询
  2。1慢查询介绍
  MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过longquerytime值的SQL,则会被记录到慢查询日志中。
  具体指运行时间超过longquerytime值的SQL,则会被记录到慢查询日志中。longquerytime的默认值为10,意思是运行10秒以上的语句。
  由他来查看哪些SQL超出了我们的最大忍耐时间值,比如一条sql执行超过5秒钟,我们就算慢SQL,希望能收集超过5秒的sql,结合之前explain进行全面分析
  2。2慢查询步骤
  问题:如何从一个大项目中,迅速的定位执行速度慢的语句。(定位慢查询)
  1)首先我们了解mysql数据库的一些运行状态如何查询(比如想知道当前mysql运行的时间一共执行了多少次selecthupdatedelete,当前连接)
  当前时间:showstatuslikeuptime;
  共执行多少次select:showstautslikecomselect;
  共执行多少次update:showstautslikecomupdate;
  共执行多少次delete:showstautslikecomdelete;
  show〔sessionglobal〕statuslike。。。如果你不写〔sessionglobal〕默认是session会话,指取出当前窗口的执行,如果你想看所有(从mysql启动到现在,则应该global)
  当前MySQL连接数:showstatuslikeconnections;
  显示慢查询次数:showstatuslikeslowqueries;
  2)开启慢查询日志
  操作说明:
  默认情况下,MySQL数据库没有开启慢查询日志,需要我们手动来设置这个参数。
  当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件。
  查看是否开启及如何开启:
  默认:SHOWVARIABLESLIKEslowquerylog;〔veribls〕
  开启:setglobalslowquerylog1;,只对当前数据库生效,如果MySQL重启后则会失效
  如果要永久生效,就必须修改配置文件my。cnf(其它系统变量也是如此)
  修改my。cnf文件,〔mysqld〕下增加或修改参数slowquerylog和slowquerylogfile后,然后重启MySQL服务器。也即将如下两行配置进my。cnf文件
  slowquerylog1slowquerylogfilevarlibmysqatguiguslow。log
  关于慢查询的参数slowquerylogfile,它指定慢查询日志文件的存放路径,系统默认会给一个缺省的文件hostnameslow。log(如果没有指定参数slowquerylogfile的话)
  3)开启了慢查询日志后,什么样的SQL才会记录到慢查询日志里面呢?
  这个是由参数longquerytime控制,默认情况下longquerytime的值为10秒,命令:SHOWVARIABLESLIKElongquerytime;
  可以使用命令修改,也可以在my。cnf参数里面修改。
  假如运行时间正好等于longquerytime的情况,并不会被记录下来。也就是说,在mysql源码里是判断大于longquerytime,而非大于等于。
  命名修改慢SQL阈值时间:setgloballongquerytime3;〔lbl〕
  看不到修改情况的话,重开连接,或者换一个语句:showglobalvariableslikelongquerytime;
  4)记录慢SQL并后续分析
  假设我们成功设置慢SQL阈值时间为3秒(setgloballongquerytime3;)。
  模拟超时SQL:selectsleep(4);
  查询当前系统中有多少条慢查询记录:showglobalstatuslikeSlowqueries;〔stets〕
  在配置文件中设置慢SQL阈值时间(永久生效):
  〔mysqld〕下配置:slowquerylog1;slowquerylogfilevarlibmysqlatguiguslow。loglongquerytime3;logoutputFILE;
  3添加适当索引
  3。1索引是什么
  MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构(索引的本质是数据结构,排序查询两种功能)。
  索引可以理解为:排好序的快速查找数据结构
  下图就是一种可能的索引方式示例:
  假如:找4号这本书,扫码得到对应的编号为91,91比34大往右边找,91比89大往右边找,然后找到(比较三次后就可以找到,然后检索出对应的物理地址)
  为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在一定的复杂度内获取到相应数据,从而快速的检索出符合条件的记录
  结论:在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构就是索引
  一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。
  我们平常所说的索引,如果没有特别指明,都是指B树(多路搜索树,并不一定是二叉的)结构组织的索引。其中聚集索引,次要索引,覆盖索引,复合索引,前缀索引,唯一索引默认都是使用B树索引,统称索引。当然,除了B树这种类型的索引之外,还有哈稀索引(hashindex)等
  3。2索引优劣势
  优势:
  类似大学图书馆建书目索引,提高数据检索的效率,降低数据库的IO成本。
  通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。
  劣势:
  实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用空间的(占空间)
  虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息。
  索引只是提高效率的一个因素,如果你的MysQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询
  3。3索引分类和建索引命令语句
  主键索引:索引值必须是唯一的,且不能为NULL
  第一种:CREATETABLEtablename(idintPRIMARYKEYautoincrement,namevarchar(10));
  第二种:ALTERTABLEtablenameADDPRIMARYKEY(columnName);
  普通索引:索引值可出现多次
  第一种:CREATEINDEXindexnameontablename(columnName);
  第二种:ALTERTABLEtablenameADDINDEXindexname(columnName);
  全文索引:主要是针对文本的检索,如:文章,全文索引只针对MyISAM引擎有效,并且只针对英文内容生效
  建表时创建
  建表CREATETABLEarticles(idINTUNSIGNEDATUOINCREMENTNOTNULLPRIMARYKEY,titleVARCHAR(200),bodyTEXT,FULLTEXT(title,body))enginemyisamcharsetutf8;指定存储引擎使用selectfromarticleswherematch(title,body)against(英文内容);只针对英语内容生效说明1、在mysql中fultext索引只针对myisam生效2、mysq1自己提供的flltext只针对英文生效sphinx(coreseek)技术处理中文工3、使用方法是match(字段名。。。)against(‘关键字)4、全文索引一个叫停止词,因为在一个文本中创建索引是一个无穷大的数,因此对一些常用词和字符就不会创建,这些词称为停止词
  ALTERTABLEtablenameADDFULLTEXTindexname(columnName);
  唯一索引:索引列的值必须唯一,但允许有空值NULL,并可以有多个。
  第一种:CREATEUNIQUEINDEXindexnameONtablename(columnName);
  第二种:ALTERTABLEtablenameADDUNIQUEINDEXindexnameON(columnName);
  单值索引:即一个索引只包含单个列,一个表可以有多个单列索引。
  第一种:CREATEINDEXindexnameONtablename(columnName);
  第二种:ALTERTABLEtablenameADDINDEXindexnameON(columnName);
  selectfromuserwherename;经常查name字段,为其建索引createindexidxusernameonuser(name);
  复合索引:即一个索引包含多个列
  第一种:CREATEINDEXindexnameONtablename(columnName1,columnName2。。。);
  第二种:ALTERTABLEtablenameADDINDEXindexnameON(columnName1,columnName2。。。);
  selectfromuserwherenameandemail;经常查name和email字段,为其建索引createindexidxusernameonuser(name,email);
  查询索引
  第一种:SHOWINDEXFROMtablename;
  第二种:SHOWKEYSFROMtablename;
  删除索引
  第一种:DROPINDEXindexnameONtablename;
  第二种:ALTERTABLEtablenameDROPINDEXindexname;
  删除主键索引:ALTERTBALEtablenameDROPPRIMARYKEY;
  查看索引的使用情况:showstatuslikeHandlerread;
  handlerreadkey:这个值越高越好,越高表示使用索引查询到的次数。
  handlerreadrndnext:这个值越高,说明查询低效。
  修改索引通常是先删除再重新建
  3。4创建索引情况分析
  哪些情况适合建索引:
  主键自动建立唯一索引
  频繁作为查询条件(where)的字段应该创建索引
  查询中与其它表关联的字段,外键关系建立索引
  单键组合索引的选择问题,who?(在高并发下倾向创建组合索引)
  查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
  查询中统计或者分组字段
  哪些情况不适合建索引:
  Where条件里用不到的字段不创建索引
  表记录太少(300w以上建)
  经常增删改的表(提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件)
  数据重复且分布平均的表字段,因此应该只为最经常查询和最经常排序的数据列建立索引。注意,如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。(比如:国籍、性别)
  假如一个表有10万行记录,有一个字段A只有T和F两种值,且每个值的分布概率天约为50,那么对这种表A字段建索引一般不会提高数据库的查询速度。
  索引的选择性:是指索引列中不同值的数目与表中记录数的比。
  如果一个表中有2000条记录,表索引列有1980个不同的值,那么这个索引的选择性就是198020000。99。一个索引的选择性越接近于1,这个索引的效率就越高
  4Explain分析(重点)
  4。1Explain介绍
  使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈在select语句之前增加explain关键字,MySQL会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL注意:如果from中包含子查询,仍会执行该子查询,将结果放入临时表中
  Explain官方文档:官网地址
  Explain的作用:
  表的读取顺序
  数据读取操作的操作类型
  哪些索引可以使用
  哪些索引被实际使用
  表之间的引用
  每张表有多少行被优化器查询
  使用Explain:
  explainsql语句
  执行计划包含的信息(重点):idselecttypetablepartitionstypepossiblekeyskeykeylenrefrowsfilteredExtra
  面试重点:id、type、key、rows、Extra
  mysqlselectfromtblemp;idNAMEdeptId1z312z413z514w525w626s737s848s9518rowsinset(0。00sec)mysqlexplainselectfromtblemp;idselecttypetablepartitionstypepossiblekeyskeykeylenrefrowsfilteredExtra1SIMPLEtblempNULLALLNULLNULLNULLNULL8100。00NULL1rowinset,1warning(0。00sec)
  4。2id(表的读取顺序)
  select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
  三种情况:
  1、id相同,执行顺序由上至下(t1、t3、t2)
  2、id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行(t3、t1、t2)
  3、id相同不同,同时存在。先走数字大的,数字相同的由上至下(t3、s1、t2)
  4。3selecttype(数据读取操作的操作类型)
  查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询。
  SIMPLE〔snpl〕:简单的select查询,查询中不包含子查询或者UNION
  PRIMARY:查询中若包含任何复杂的子部分,最外层查询则被标记为(最后加载的那个)
  SUBQUERY〔kwri〕:在SELECT或WHERE列表中包含了子查询
  DERIVED〔dravd〕:在FROM列表中包含的子查询被标记为DERIVED(衍生)MySQL会递归执行这些子查询,把结果放在临时表里
  UNION〔junin〕:若第二个SELECT出现在UNION之后,则被标记为UNION;若UNION包含在FROM子句的子查询中外层SELECT将被标记为:DERIVED
  UNIONRESULT〔rzlt〕:从UNION表获取结果的SELECT(两个select语句用UNION合并)
  4。4table(显示执行的表名)
  这一列表示explain的一行正在访问哪个表。
  当from子句中有子查询时,table列是格式,表示当前查询依赖idN的查询,于是先执行idN的查询。当有union时,UNIONRESULT的table列的值为union1,2,1和2表示参与union的select行id。
  4。5type(访问类型排列)
  显示查询使用了何种类型
  访问类型排列:systemconsteqrefreffulltextrefornullindexmergeuniquesubqueryindexsubqueryrangeindexALL
  type常用八种类型:
  结果值从最好到最坏依次是(重点)::systemconsteqrefrefrangeindexALL
  一般来说,得保证查询至少达到range级别,最好能达到ref
  详细说明
  system:表只有一行记录(等于系统表),这是const类型的特列,平时不会出现,这个也可以忽略不计。
  const:表示通过索引一次就找到了,const用于比较primarykey或者unique索引。因为只匹配一行数据,所以很快如将主键置于where列表中,MySQL就能将该查询转换为一个常量。
  eqref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。
  ref:非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体
  range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引一般就是在你的where语句中出现了between、、、in等的查询。这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,而结束语另一点,不用扫描全部索引
  index:FullIndexScan,index与ALL区别为index类型只遍历索引列。这通常比ALL快,因为索引文件通常比数据文件小(也就是说虽然all和Index都是读全表,但index是从索引中读取的,而all是从硬盘中读的)
  all:FullTableScan,将遍历全表以找到匹配的行
  工作案例:经理这条SQL我跑了一下Explain分析,在系统上可能会有ALL全表扫描的情况,建议尝试一下优化。我把这条SQL改了改,我优化后是这么写,这个效果已经从ALL变成了
  4。6possiblekeys(哪些索引可以使用)
  显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段火若存在索引,则该索引将被列出,但不一定被查询实际使用(系统认为理论上会使用某些索引)
  4。7key(哪些索引被实际使用)
  实际使用的索引。如果为NULL,则没有使用索引(要么没建,要么建了失效)
  查询中若使用了覆盖索引,则该索引仅出现在key列表中
  覆盖索引:建的索引字段和查询的字段一致,如下图
  4。8keylen(消耗的字节数)
  表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好
  keylen显示的值为索引字段的最大可能长度,并非实际使用长度,即keylen是根据表定义计算而得,不是通过表内检索出的
  4。9ref(表之间的引用)
  显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值。
  4。10rows(每张表有多少行被优化器查询)
  根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数(越小越好)
  未建索引时:
  建索引后:扫描行数减少
  4。11Extra〔ekstr〕
  包含不适合在其他列中显示但十分重要的额外信息
  信息种类:Usingfilesort、Usingtemporary、Usingindex、Usingwhere、Usingjoinbuffer、impossiblewhere、selecttablesoptimizedaway、distinct
  Usingfilesort(需要优化)
  说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作称为文件排序
  Usingtemporary(需要优化)
  使了用临时表保存中间结果,MysQL在对查询结果排序时使用临时表。常见于排序orderby和分组查询groupby
  Usingindex(good)
  表示相应的select操作中使用了覆盖索引(CoveringIndex),避免访问了表的数据行,效率不错!
  情况一:
  情况二:
  覆盖索引索引覆盖(CoveringIndex)。
  理解方式一:就是select的数据列只用从索引中就能够取得,不必读取数据行,MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件,换句话说查询列要被所建的索引覆盖。
  理解方式二:索引是高效找到行的一个方法,但是一般数据库也能使用索引找到一个列的数据,因此它不必读取整个行。毕竟索引叶子节点存储了它们索引的数据;当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引包含了(或覆盖了)满足查询结果的数据就叫做覆盖索引。
  注意:
  如果要使用覆盖索引,一定要注意select列表中只取出需要的列,不可select
  因为如果将所有字段一起做索引会导致索引文件过大,查询性能下降
  Usingwhere:表明使用了where过滤。
  Usingjoinbuffer:使用了连接缓存
  impossiblewhere:where子句的值总是false,不能用来获取任何元组
  selecttablesoptimizedaway
  在没有GROUPBY子句的情况下,基于索引优化MINMAX操作,或者对于MyISAM存储引擎优化COUNT()操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。
  distinct
  优化distinct操作,在找到第一匹配的元组后即停止找同样值的动作。
  4。12练习
  写出下图的表的执行顺序
  第一行(执行顺序4):id列为1,表示是union里的第一个select,selecttype列的primary表示该查询为外层查询,table列被标记为,表示查询结果来自一个衍生表,其中derived3中3代表该查询衍生自第三个select查询,即id为3的select。【selectd1。name】
  第二行(执行顺序2):id为3,是整个查询中第三个select的一部分。因查询包含在from中,所以为derived。【selectid,namefromt1whereothercolumn’’】
  第三行(执行顺序3):select列表中的子查询selecttype为subquery,为整个查询中的第二个select。【selectidfromt3】
  第四行(执行顺序1):selecttype为union,说明第四个select是union里的第二个select,最先执行【selectname,idfromt2】
  第五行(执行顺序5):代表从union的临时表中读取行的阶段,table列的union1,4表示用第一个和第四个select的结果进行union操作。【两个结果union操作】
  5索引优化
  5。1索引单表优化案例
  建表:
  CREATETABLEIFNOTEXISTSarticle(idINT(10)UNSIGNEDNOTNULLPRIMARYKEYAUTOINCREMENT,authoridINT(10)UNSIGNEDNOTNULL,categoryidINT(10)UNSIGNEDNOTNULL,viewsINT(10)UNSIGNEDNOTNULL,commentsINT(10)UNSIGNEDNOTNULL,titleVARCHAR(255)NOTNULL,contentTEXTNOTNULL);INSERTINTOarticle(authorid,categoryid,views,comments,title,content)VALUES(1,1,1,1,1,1),(2,2,2,2,2,2),(1,1,3,3,3,3);查询mysqlselectfromarticle;idauthoridcategoryidviewscommentstitlecontent1111111222222231133333rowsinset(0。00sec)
  案例
  要求:查询categoryid为1且comments大于1的情况下,views最多的articleid
  功能实现mysqlSELECTid,authoridFROMarticleWHEREcategoryid1ANDcomments1ORDERBYviewsDESCLIMIT1;idauthorid311rowinset(0。00sec)explain分析mysqlexplainSELECTid,authoridFROMarticleWHEREcategoryid1ANDcomments1ORDERBYviewsDESCLIMIT1;idselecttypetablepartitionstypepossiblekeyskeykeylenrefrowsfilteredExtra1SIMPLEarticleNULLALLNULLNULLNULLNULL333。33Usingwhere;Usingfilesort1rowinset,1warning(0。00sec)
  结论:很显然,type是ALL,即最坏的情况。Extra里还出现了Usingfilesort,也是最坏的情况。优化是必须的
  开始优化
  新建索引(给WHERE语句后使用的字段添加索引)
  创建方式:
  createindexidxarticleccvonarticle(categoryid,comments,views);
  ALTERTABLEarticleADDINDEXidxarticleccv(categoryid,comments,views);
  索引用处不大,删除:DROPINDEXidxarticleccvONarticle;
  结论:
  type变成了range,这是可以忍受的。但是extra里使用Usingfilesort仍是无法接受的。
  但是我们已经建立了索引,为啥没用呢?
  这是因为按照BTree索引的工作原理,先排序categoryid,如果遇到相同的categoryid则再排序comments,如果遇到相同的comments则再排序views。
  当comments字段在联合索引里处于中间位置时,因comments1条件是一个范围值(所谓range),MySQL无法利用索引再对后面的views部分进行检索,即range类型查询字段后面的索引无效。
  改进
  上次创建索引相比,这次不为comments字段创建索引
  结论:type变为了ref,ref中是const,Extra中的Usingfilesort也消失了,结果非常理想
  5。2索引两表优化案例
  建表:
  CREATETABLEIFNOTEXISTSclass(idINT(10)UNSIGNEDNOTNULLAUTOINCREMENT,cardINT(10)UNSIGNEDNOTNULL,PRIMARYKEY(id));CREATETABLEIFNOTEXISTSbook(bookidINT(10)UNSIGNEDNOTNULLAUTOINCREMENT,cardINT(10)UNSIGNEDNOTNULL,PRIMARYKEY(bookid));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOclass(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));INSERTINTObook(card)VALUES(FLOOR(1(RAND()20)));查询mysqlselectfromclass;idcard11722318445468798191810611151215131214151518162171818519720121221rowsinset(0。00sec)mysqlselectfrombook;bookidcard1821433416586127178891010311412121391471561681731811195201120rowsinset(0。00sec)
  开始Explain分析:type都是all,需要优化(总有一个表来添加索引驱动)
  左连接为左表加索引
  删除索引:dropindexyonclass;
  左连接为右表添加索引
  删除索引:dropindexYonbook;
  案例:如果别人建的索引位置不对,只需要自己查询时调整左右表的顺序即可
  结论:
  第二行的type变为了ref,rows也变少了,优化比较明显。这是由左连接特性决定的。LEFTJOIN条件用于确定如何从右表搜索行,左边一定都有,所以右边是我们的关键点,一定需要在右表建立索引(小表驱动大表)。
  左连接,右表加索引
  同理:右连接,左表加索引
  5。3索引三表优化案例
  建表:
  CREATETABLEIFNOTEXISTSphone(phoneidINT(10)UNSIGNEDNOTNULLAUTOINCREMENT,cardINT(10)UNSIGNEDNOTNULL,PRIMARYKEY(phoneid))ENGINEINNODB;INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));INSERTINTOphone(card)VALUES(FLOOR(1(RAND()20)));查询mysqlselectfromphone;phoneidcard110213317455126771581791710141119121313514815216817111814191320520rowsinset(0。00sec)
  用上一节两个表,删除他们的索引:
  三表查询语句应为:SELECTFROMclassLEFTJOINbookONclass。cardbook。cardLEFTJOINphoneONbook。cardphone。card;
  创建索引:
  应该为第一个LFETJOIN的右表book建索引
  altertablebookaddindexY(card);
  应该为第二个LFETJOIN的右表phone建索引
  altertablephoneaddindexz(card);
  Explain分析:
  后2行的type都是ref且总rows优化很好,效果不错。因此索引最好设置在需要经常查询的字段中
  结论:
  Join语句的优化
  尽可能减少Join语句中的NestedLoop的循环总次数:永远用小结果集驱动大的结果集(比如:书的类型表驱动书的名称表)。
  优先优化NestedLoop的内层循环,保证Join语句中被驱动表上Join条件字段已经被索引。
  当无法保证被驱动表的Join条件字段被索引且内存资源充足的前提下,不要太吝惜JoinBuffer的设置
  5。4索引失效案例
  建表:
  CREATETABLEstaffs(idINTPRIMARYKEYAUTOINCREMENT,nameVARCHAR(24)NOTNULLDEFAULTCOMMENT姓名,ageINTNOTNULLDEFAULT0COMMENT年龄,posVARCHAR(20)NOTNULLDEFAULTCOMMENT职位,addtimeTIMESTAMPNOTNULLDEFAULTCURRENTTIMESTAMPCOMMENT入职时间)CHARSETutf8COMMENT员工记录表;INSERTINTOstaffs(name,age,pos,addtime)VALUES(z3,22,manager,NOW());INSERTINTOstaffs(name,age,pos,addtime)VALUES(July,23,dev,NOW());INSERTINTOstaffs(name,age,pos,addtime)VALUES(2000,23,dev,NOW());ALTERTABLEstaffsADDINDEXindexstaffsnameAgePos(name,age,pos);
  1、全值匹配我最爱
  2、最佳左前缀法则(重要!):如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过复合索引中间列。
  中间列不能断:
  3、不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描。
  4、存储引擎不能使用索引中范围条件右边的列(范围之后全失效,范围列并不是做的查询而是排序)。
  5、尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select。
  6、mysql在使用不等于(!或者)的时候无法使用索引会导致全表扫描。
  7、isnull,isnotnull也无法使用索引。
  8、like以通配符开头(’abc’),mysql索引失效会变成全表扫描的操作(写在最右边索引不会失效,或覆盖索引)。
  问题:解决like字符串时索引不被使用的方法?采用覆盖索引的方法!
  建表:
  CREATETABLEtbluser(idINT(11)NOTNULLAUTOINCREMENT,nameVARCHAR(20)DEFAULTNULL,ageINT(11)DEFAULTNULL,emailVARCHAR(20)DEFAULTNULL,PRIMARYKEY(id))ENGINEINNODBAUTOINCREMENT1DEFAULTCHARSETutf8;INSERTINTOtbluser(name,age,email)VALUES(1aa1,21,a163。com);INSERTINTOtbluser(name,age,email)VALUES(2bb2,23,b163。com);INSERTINTOtbluser(name,age,email)VALUES(3cc3,24,c163。com);INSERTINTOtbluser(name,age,email)VALUES(4dd4,26,d163。com);查询mysqlselectfromtbluser;idnameageemail11aa121a163。com22bb223b163。com33cc324c163。com44dd426d163。com4rowsinset(0。00sec)
  创建索引:
  CREATEINDEXidxusernameAgeONtbluser(NAME,age);
  索引成功使用:
  索引失效:
  总结:写在最右边,如果非要写在最左边,就使用覆盖索引
  9、字符串不加单引号索引失效。
  Explain分析:
  10、少用or,用它来连接时会索引失效
  5。5索引面试题分析
  建表:
  createtabletest03(idintprimarykeynotnullautoincrement,c1char(10),c2char(10),c3char(10),c4char(10),c5char(10));insertintotest03(c1,c2,c3,c4,c5)values(a1,a2,a3,a4,a5);insertintotest03(c1,c2,c3,c4,c5)values(b1,b2,b3,b4,b5);insertintotest03(c1,c2,c3,c4,c5)values(c1,c2,c3,c4,c5);insertintotest03(c1,c2,c3,c4,c5)values(d1,d2,d3,d4,d5);insertintotest03(c1,c2,c3,c4,c5)values(e1,e2,e3,e4,e5);查看表结构mysqlselectfromtest03;idc1c2c3c4c51a1a2a3a4a52b1b2b3b4b53c1c2c3c4c54d1d2d3d4d55e1e2e3e4e55rowsinset(0。00sec)
  建索引:
  createindexidxtest03c1234ontest03(c1,c2,c3,c4);查看索引mysqlshowindexfromtest03;TableNonuniqueKeynameSeqinindexColumnnameCollationCardinalitySubpartPackedNullIndextypeCommentIndexcommenttest030PRIMARY1idA2NULLNULLBTREEtest031idxtest03c12341c1A5NULLNULLYESBTREEtest031idxtest03c12342c2A5NULLNULLYESBTREEtest031idxtest03c12343c3A5NULLNULLYESBTREEtest031idxtest03c12344c4A5NULLNULLYESBTREE5rowsinset(0。00sec)
  1)逐一增加列
  2)交换条件顺序不影响索引,但最好按照建索引顺序来写SQL
  3)限定范围
  4)orderby
  5)groupby
  定值、范围还是排序,一般orderby是给个范围
  groupby基本上都需要进行排序,会有临时表产生
  建议:
  对于单值索引,尽量选择针对当前query过滤性更好的索引。
  在选择组合索引的时候,当前Query中过滤性最好的字段在索引字段顺序中,位置越靠左越好。
  在选择组合索引的时候,尽量选择可以能够包含当前query中的where字句中更多字段的索引。
  尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的。
  5。6总结
  优化总结口诀
  全值匹配我最爱,最左前缀要遵守;
  带头大哥不能死,中间兄弟不能断;
  索引列上少计算,范围之后全失效;
  LIKE百分写最右,覆盖索引不写;
  不等空值还有OR,索引影响要注意;
  VAR引号不可丢,SQL优化有诀窍。
  5。7小表驱动大表
  EXISTS〔zsts〕语法:SELECT。。。FROMtableWHEREEXISTS(subquery)
  该语法可以理解为:将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE或FALSE)来决定主查询的数据结果是否得以保留
  提示:
  EXSTS(subquey)只返回TRUE或FALSE,因此子查询中的SELECT也可以是SELECT1或select‘X’,官方说法是实际执行时会忽略SELECT清单,因此没有区别。
  EXISTS子查询的实际执行过程可能经过了优化而不是我们理解上的逐条对比,如果担忧效率问题,可进行实际检验以确定是否有效率问题。
  EXISTS子查询往往也可以用条件表达式,其他子查询或者JOIN来替代,何种最优需要具体问题具体分析
  in和exists用法:
  5。8Orderby优化
  1、ORDERBY之后子句,尽量使用Index方式排序,避免使用FileSort方式排序
  建表:
  createtabletblA(idintprimarykeynotnullautoincrement,ageint,birthtimestampnotnull);insertintotblA(age,birth)values(22,now());insertintotblA(age,birth)values(23,now());insertintotblA(age,birth)values(24,now());createindexidxAageBirthontblA(age,birth);查询mysqlselectfromtblA;agebirth222021040419:31:45232021040419:31:45242021040419:31:453rowsinset(0。00sec)mysqlshowindexfromtblA;TableNonuniqueKeynameSeqinindexColumnnameCollationCardinalitySubpartPackedNullIndextypeCommentIndexcommenttbla1idxAageBirth1ageA3NULLNULLYESBTREEtbla1idxAageBirth2birthA3NULLNULLBTREE2rowsinset(0。00sec)
  关注点:是orderby之后会不会产生Usingfilesort
  MySQL支持二种方式的排序,FileSort和lIndex,Index效率高,它指MySQL扫描索引本身完成排序。FileSort方式效率较低。
  ORDERBY满足两情况,会使用Index方式排序:
  ORDERBY语句使用索引最左前列。
  使用where子句与OrderBY子句条件列组合满足索引最左前列。
  2、尽可能在索引上完成排序操作,遵照建索引的最佳左前缀
  3、如果不在索引列上,mysql的filesort有两种算法(自动启动)
  双路排序
  MySQL4。1之前是使用双路排序,字面意思就是两次扫描磁盘,最终得到数据,读取行指针和OrderBy列,对他们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读对应的数据输出。
  从磁盘取排序字段,在buffer进行排序,再从磁盘取其他字段。
  取一批数据,要对磁盘进行了两次扫描,众所周知,IO是很耗时的,所以在mysql4。1之后,出现了第二种改进的算法,就是单路排序
  单路排序
  从磁盘读取查询需要的所有列,按照orderby列在buffer对它们进行排序,然后扫描排序压的列表进行输出,它的效率更快一些,避免了第二次读取数据。并且把随机IO变成了顺序IO,但是它会使用更多的空间,因为它把每一行都保存在内存中了
  结论及引申出的问题
  由于单路是后出的,总体而言好过双路
  但是用单路有问题,在sortbuffer中,方法B比方法A要多占用很多空间,因为方法B是把所有字段都取出,所以有可能取出的数据的总大小超出了sortbuffer的容量,导致每次只能取sortbuffer容量大小的数据,进行排序(创建tmp文件,多路合并),排完再取取
  sortbuffer容量大小,再排从而多次IO。
  本来想省一次IO操作,反而导致了大量的IO操作,反而得不偿失
  4、优化策略
  增大sortbuffersize参数的设置
  增大maxlengthforsortdata参数的设置
  Why?
  5、小总结:
  5。9Groupby优化
  groupby实质是先排序后进行分组,遵照索引建的最佳左前缀。
  当无法使用索引列,增大maxlengthforsortdata参数的设置增大sortbuffersize参数的设置。
  where高于having,能写在where限定的条件就不要去having限定了
  在groupby后面加个orderbynull就可以防止排序
  有些情况下,可以使用连接来替代子查询。因为使用join,MySQL不需要在内存中创建临时表
  简单处理方式selectfomdept,empwheredept。deptnoemp。deptno;左连接更优selectfromdeptleftjoinemnpondept。deptnoemp。deptno;
  6ShowProfile分析(重点)
  ShowProfile是mysql提供可以用来分析当前会话中语句执行的资源消耗情况。可以用于SQL的调优的测量
  官网文档
  默认情况下,参数处于关闭状态,并保存最近15次的运行结果
  分析步骤:
  1、是否支持,看看当前的mysql版本是否支持:showvariableslikeprofiling;
  默认是关闭,使用前需要开启
  2、开启功能,默认是关闭,使用前需要开启:setprofilingon;
  3、运行SQL(随便运行用来测试)
  mysqlselectfromempgroupbyid10limit150000;mysqlselectfromempgroupbyid20orderby5;
  4、查看结果:showprofiles;
  mysqlshowprofiles;QueryIDDurationQuery10。00204000showvariableslikeprofiling20。55134250selectfromempgroupbyid10limit15000030。56902000selectfromempgroupbyid20orderby53rowsinset,1warning(0。00sec)
  5、诊断SQL,showprofilecpu,blockioforqueryID号;(ID号为第4步QueryID列中数字)
  mysqlshowprofilecpu,blockioforquery3;StatusDurationCPUuserCPUsystemBlockopsinBlockopsoutstarting0。0000490。0000000。000000NULLNULLcheckingpermissions0。0000050。0000000。000000NULLNULLOpeningtables0。0000120。0000000。000000NULLNULLinit0。0000210。0000000。000000NULLNULLSystemlock0。0000090。0000000。000000NULLNULLoptimizing0。0000030。0000000。000000NULLNULLstatistics0。0000170。0000000。000000NULLNULLpreparing0。0000080。0000000。000000NULLNULLCreatingtmptable0。0000450。0000000。000000NULLNULLSortingresult0。0000040。0000000。000000NULLNULLexecuting0。0000020。0000000。000000NULLNULLSendingdata0。5687040。5468750。046875NULLNULLCreatingsortindex0。0000480。0000000。000000NULLNULLend0。0000030。0000000。000000NULLNULLqueryend0。0000050。0000000。000000NULLNULLremovingtmptable0。0000060。0000000。000000NULLNULLqueryend0。0000030。0000000。000000NULLNULLclosingtables0。0000040。0000000。000000NULLNULLfreeingitems0。0000610。0000000。000000NULLNULLcleaningup0。0000150。0000000。000000NULLNULL20rowsinset,1warning(0。00sec)
  参数备注(写在代码中):showprofilecpu,blockioforquery3;(如此代码中的cpu,block)
  ALL:显示所有的开销信息。
  BLOCKIO:显示块lO相关开销。
  CONTEXTSWITCHES:上下文切换相关开销。
  CPU:显示CPU相关开销信息。
  IPC:显示发送和接收相关开销信息。
  MEMORY:显示内存相关开销信息。
  PAGEFAULTS:显示页面错误相关开销信息。
  SOURCE:显示和Sourcefunction,Sourcefile,Sourceline相关的开销信息。
  SWAPS:显示交换次数相关开销的信息。
  6、日常开发需要注意的结论(Status列中的出现此四个问题严重)
  convertingHEAPtoMyISAM:查询结果太大,内存都不够用了往磁盘上搬了。
  Creatingtmptable:创建临时表,拷贝数据到临时表,用完再删除
  Copyingtotmptableondisk:把内存中临时表复制到磁盘,危险!
  locked:锁了
  7MySQL配置优化
  修改my。ini文件:
  端口号:port3306,主机也要修改mysqlconnect()
  最大并发数:maxconnections151(可以改为2000)
  最重要的参数就是内存,我们主要用的innodb引擎,所以下面两个参数调的很大
  innodbadditionalmempoolsize64M
  innodbbufferpoolsize1G
  对于myisam,需要调整keybuffersize(增加10倍即可)
  如果你的操作系统是64的,内存足够,请选择使用64的mysql安装程序

深圳一家人聚餐喝光6瓶茅台,服务员捡走酒瓶,行家安享晚年吧王大姐老家在东北,前几年和朋友一起来深圳打工,期间也换了几份工作,直到现在在一家饭店做服务员才算稳定下来,饭店包吃包住,每月到手的工资5000多,这个工资待遇可比她老家多出很多……市场摊贩剖析市场经济奥秘,戳穿新旧资本集团200年诡辩谎言大家好,我是市场一摊贩郑高亮,欢迎大家参与市场摊贩剖析市场经济:戳穿新旧资本集团为了能猖狂贪婪货币放贷二次发币权益和发行美元纸币操纵世界各国政治经济,200年来精心设计制造维护……2月品牌热搜榜发布!辉瑞特斯拉苹果等上榜中新经纬与梅花数据联合发布的2月品牌热搜榜显示,2023年2月,苹果公司收获了102个热搜,位于当月品牌热搜榜榜首。2月还有哪些品牌上榜?一起来看看吧!TOP1:苹……直击精子进入女人身体的全过程,网友原来我是这样被生出来的这是我讲述的第6个科普故事编辑小龙科普jy所见所得,都很科学小时候我们对这整个世界都感到非常好奇例如看到一辆火车驶过就会开心的大笑并且……今日分享03041、我一直想说一个道理:就是迟到不是迟到者的课题。而是等待者的课题。然后这个道理可以推广到很多关系里。(这里不牵扯任何对错的评价)不是谁痛苦谁改变……曲面屏不贵了,盘点三款值得入手的曲面屏手机,最低售价1309曲面屏由于能够给消费者带来更大化的可视面积,两侧曲面的屏幕能够很好的把手机中框隐藏掉,能够带来更加沉浸式的体验,深得消费者的喜爱,曾经的曲面屏只能够被使用到高端旗舰上,即便是如……露营地建设未来之路在哪里?海南体博会给你一个全新的答案新海南客户端、南海网、南国都市报3月15日消息(记者陈望)自2019年以来,我国露营产业得到了爆发式增长,但也有一部分中小型营地经营不善,行业内也开始对露营产业未来发展之路出现……这次网易说不!魔兽世界停服倒计时,暴雪已与多个合作方展开会谈1月24日0点,是《魔兽世界》《炉石传说》《守望先锋》等暴雪游戏国服预计停服的日子。此前,不少国内游戏玩家仍然期待网易与暴雪能够继续谈判,事情能够出现转机。但1月17日,……新年上UC,来打造一款符合你习惯的专属浏览器在日常上网的过程中,浏览器应该是必不可缺的软件之一。就拿小编来说,通勤路上会看些新闻或小说来打发时间,晚上到家刷刷视频,都是通过浏览器来进行的。而市面上浏览器众多,在经过对比后……海口邂逅天空之山品味醉美生活有没有想过于椰树银沙间听海浪轻吟?或选个雅致的所在品一杯咖啡、读几页好书、看一场艺术展?再或者与最亲密的爱人相拥山巅看日升月落?那么,来吧,让我们相约海口天空之山驿站,一起领略……飞猪春季出游快报2小时高铁圈周末游最热门国内游客的踏青赏花需求持续走高。飞猪供图红网时刻新闻3月22日讯(记者何超通讯员汪星州)春分已至,又到了花花世界的最佳赏期。3月21日,飞猪发布的《春季出游快报》显示,近……灌阳水车桃花似锦美如画阳春三月,风和日丽,广西灌阳县水车镇千亩桃园桃花争相竞开,游客在画一样的花中诗一样的景里品味春光。千亩桃园桃花争相竞开。近年来,水车镇在灌阳县委、县政府的领导下,以……
iPhone14真机曝光?双打孔屏A15满血版,支持120H近一二年,最难突破的应该是屏幕设计,从折叠屏到屏下摄像头设计,一直卡在屏幕上,至今也没有厂商取得突破。目前,所发布的折叠屏手机在长时间的折叠下会出现折痕,甚至是屏幕破裂,无法正……恭喜!国乒27岁名将公布恋情,男友胖胖的,表白藏不住的喜欢他北京时间2月14日,情人节,国乒27岁的名将顾玉婷公开了恋情,晒出了与男友的照片。顾玉婷写道:给大家介绍一下,这位先生是我宇宙限量版快乐从我们认识的那天起,就再也没有从我……价格感人,华为nova10SE发布,性能成最大短板华为被制裁后,对产品线进行了调整,荣耀整体打包卖掉,最终只保留了Mate系列,P系列,Nova系列和畅享系列,其中Mate系列和P系列属于高端旗舰产品,Nova系列属于中端产品……两味药泡水,补肝肾强筋骨,化瘀止痛,生精养血,堪称关节润滑液大家好,我是沈医生,今天给分享一个两味药的小方子,堪称关节润滑剂,不仅补肝补肾,补精养血,还可升阳化瘀,暖腰腿关节,止全身各种疼痛,让你腰不酸,腿不疼,全身有力!总是腰疼……比亚迪吉利再度力压南北大众,自主强合资弱会成常态吗?车企年末冲刺,自主品牌明显提速,比亚迪、吉利汽车批售、零售销量,均超越一汽大众。12月8日,全国乘用车市场信息联席会(以下简称乘联会)发布11月全国乘用车市场数据。202……微信群里,很少说话又不退群的,往往是这3种人每个人的微信里都会有很多群。上班时,消息最多的是工作群;休息时,家族群滴滴响个不停;聚会前,同学群,朋友群又会活跃起来。但大家有没有注意到,无论是哪种群,总会有那么……男星也有医美后遗症!华晨宇脸小挂不住肉,王一博法令纹越来越深娱乐圈从来不乏帅哥美女,颜值是很重要的武器。为了保持美丽,很多明星都会选择医美保养自己,但医美有风险,后遗症更是一大堆。最近播出的综艺节目中,钟汉良就因为脸部僵硬,引发热议。跟……1MOREComfoBudsMini评测小而精小而美小而强你是否还记得2016年的那个夏天,在苹果发布了AirPods之后,这款产品便凭借着自己小巧轻便、无感佩戴等特点在上市之后就取得了非常不错的市场反响,并且AirPods身上的特点……2022年山东省蔬菜产业数据分析简报山东省位于中国东部,黄河下游,大体分为鲁中(济南、淄博、潍坊、泰安、滨州邹平)、鲁南(菏泽、济宁、临沂、日照、枣庄)、鲁西(聊城、德州的南部)、鲁北(东营、滨州、潍坊的西北部、……6元买典藏?元歌新皮作品惊艳,傀儡变赛车!神明!机甲大家好,我是秋豆。元歌的缘梦系列新皮肤已经开启首轮投票,其中不乏一些让人超级惊艳的作品,秋豆想和大家分享一下自己觉得一些优秀的作品,供大家投票参考。(注:图片可放大看)……二月十九观音会水观音景区门票车票都免费!水观音景区二月十九观音会欢迎您!3月19日至21日(农历二月十七至十九)观音会期间水观音门票免费,南山门至水观音段观光车车票免费水观音景区位于金牛古蜀道南来北……2022。03。15股市收评恐慌加剧!A股全线暴跌美股隔夜美股继续下跌,截至收盘,道指收平,纳指下跌2。04,标普500下跌0。74。尽管隔夜原油、天然气等大宗商品大幅下跌,但在俄乌局势胶着、美联储加息在即、美债收……
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网