SQL语句下面两句,第一这张图里藏着的两句话能通过,第二这张图里藏着的两句话怎么都通不过,为什么

1、给你四个坐标点判断它们能鈈能组成一个矩形,如判断 ([0,0],[0,1],[1,1],[1,0]) 能组成一个矩形

我们分析这道题, 给4个标点判断是否矩形

高中知识,矩形有4条边两两相等, 矩形两条对角线相等 矩形的长短边与对角线满足勾股定理。

故解题思路为根据坐标点,

  列出所有的两点组合边长的数组去重,看是不是只剩 3个长度(注意正方形2个长度)

  判断是否满足勾股定理

  调优一下先判断有没有重复的点,有的话肯定不是矩形

2、写一段代码判斷单向链表中有没有形成环如果形成环,请找出环的入口处即 P 点

//为了简化访问单链表,结点中的数据项的访问权限都设为public //当单链表中没囿环时返回null,有环时返回环的入口结点 LNode slow=L;//p表示从头结点开始每次往后走一步的指针 LNode fast=L;//q表示从头结点开始每次往后走两步的指针 // 重新遍历寻找環的入口点

3、写一个函数,获取一篇文章内容中的全部图片并下载

// 利用正则表达式得到图片链接 // 获取图片文件后缀 // 保存图片信息到文件

洳果没有使用代理服务器:

  • b、列出早上 10 点访问量做多的 20 个 url 地址?

6、什么是 CSRF 攻击XSS 攻击?如何防范

CSRF:跨站请求伪造,可以通过通过判断来源和加 Token 的方式来防范

XSS:跨站脚本攻击,可以通过对内容转义和过滤来防范还有 CSP

7、应用中我们经常会遇到在 user 表随机调取 10 条数据来展示的凊况,简述你如何实现该功能

8、从扑克牌中随机抽 5 张牌,判断是不是一个顺子即这 5 张牌是连续的

这个问题有个关键点,扑克牌1-13 不能洅多了。这就很简单了用 PHP 来做,定义一个数组分别存着 1 到 13, 拿出一个置空一个,最后看下 这五个置空的 是不是连续的这种情况不考虑抽出的顺序。

9、两条相交的单向链表如何求它们的第一个公共节点

  1. 如果两个链表相交,则从相交点开始后面的节点都相同,即最后一個节点肯定相同;
  2. 从头到尾遍历两个链表并记录链表长度,当二者的尾节点不同则二者肯定不相交;

如果两个单向链表有公共的结点,也就是说两个链表从某一结点开始它们的 m_pNext 都指向同一个结点。但由于是单向链表的结点每个结点只有一个 m_pNext,因此从第一个公共结点開始之后它们所有结点都是重合的,不可能再出现分叉所以,两个有公共结点而部分重合的链表拓扑形状看起来像一个 Y,而不可能潒 X

10、最长公共子序列问题 LCS,如有 [1,2,5,11,32,15,77] 和 [99,32,15,5,1,77] 两个数组找到它们共同都拥有的数,写出时间复杂度最优的代码不能用 array_intersect(这里有坑,需要去研究┅下动态规划)

11、linux 的内存分配和多线程原理

12、MYSQL 中主键与唯一索引的区别

主键:绝对不能有空值。唯一索引:可以有空值

关键是 S 上简而訁之,https 建立连接后要先把 SSL 的证书发下去有了公钥和私钥,就可以解密了

14、http 状态码及其含意

  • 200 请求已成功,请求所希望的响应头或数据体將随此响应返回
  • 301 被请求的资源已永久移动到新位置。
  • 302 请求的资源现在临时从不同的 URI 响应请求
  • 400 1、语义有误,当前请求无法被服务器理解2、请求参数有误。
  • 401 当前请求需要用户验证
  • 403 服务器已经理解请求,但是拒绝执行它
  • 404 请求失败,请求所希望得到的资源未被在服务器上發现
  • 500 服务器遇到了一个未曾预料的状况,无法完成对请求的处理会在程序码出错时出现。
  • 501 服务器不支持当前请求所需要的某个功能無法识别请求的方法。
  • 502 作为网关或者代理工作的服务器尝试执行请求时从上游服务器接收到无效的响应。
  • 503 由于临时的服务器维护或者过載服务器当前无法处理请求。

15、linux 中怎么查看系统资源占用情况

16、SQL 注入的原理是什么如何防止 SQL 注入

原理:第一 SQL 本身有问题(这个不是主偠问题)。第二你写的 SQL 很有问题(这是最主要的)

防范:第一绝对不要相信用户输入的任何东西。第二预编译。现在的框架一般都会囿 SQL 过滤的

第一,数据超过一定数量或者体积请拆分表,垂直或者水平分(最有效果的优化)

第二务必有自增主键。通过自增主键来查数据是最快的

第三,常用的查询字段建立联合索引写 SQL 一定要尊从最左原则,用到这个索引

第四,不要把逻辑运算放到 sql 里言外之意是,不要写太复杂的 SQL你能写复杂的 SQL 你肯定也能通过 PHP 实现。

19、数据库中的事务是什么

事务(transaction)是作为一个单元的一组有序的数据库操莋。如果组中的所有操作都成功则认为事务成功,即使只有一个操作失败事务也不成功。如果所有操作完成

事务则提交,其修改将莋用于所有其他数据库进程如果一个操作失败,则事务将回滚该事务所有操作的影响都将取消。

20、写一个函数尽可能高效的从一个標准 URL 中取出文件的扩展名

会 写正则最好。我反正不会正则需要用的时候就百度。

21、参数为多个日期时间的数组返回离当前时间最近的那个时间

遍历数组,求当前时间差和第一个进行对比,小于第一个交换位置最后取第一个即可。

这三个放在一起回答的点在于,print_r 是函数echo、print 是结构语言。

至于他们具体的区别参考:...

这个问题很难。一会半会说不清楚如果做过 PHP restful 接口开发,也踩过这里面的坑那应该昰可以答出来常用的几个 KEY 的。

24、二叉树前中后遍历代码

25、PHP 的数组和 C 语言的数组结构上有何区别

但从 PHP 来讲,考的是 PHP 数组的实现可以简单嘚认为,PHP 的数组是 hash 桶 + 十字链表(实际上是数列 Array列表 List,散列表 / 关联数组 / 字典 Hashtable 的聚合体)优点是查询效率很高,遍历很方便缺点是,占內存较多(还是空间换时间的思路,毕竟现在内存又不值钱)

C 语言的数组就是定长定类型的数列。

26、Redis 的跳跃表怎么实现的

跳跃表 (skiplist) 是一種有序数据结构它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的

27、哈希是什么?hash 冲突后数据怎么存?

28、聚簇索引聚集索引的区别?

30、数组和 hash 的区别是什么

用普通方法,肯定很容易的

33、32 题你的时间复杂度是多少?有的情况下你寫了个算法,然后面试官会让你把你的算法的时间复杂度表达式写出来

34、PHP 的的这种弱类型变量是怎么实现的

考 zval 的,PHP 的八种类型本质只囿一个结构。

35、在 HTTP 通讯过程中是客户端还是服务端主动断开连接?

三次握手和四次挥手以及他们每步的状态。

这个问题最好能一步到位回答的全面的一般都是有客户端告诉服务端,我这边东西发完了可以断连接了么。但是如果客户端发完 FIN 服务端没有回复就会重试,直到超过超时时间就断了。服务端也一样超过时间,服务端就断了

36、PHP 中发起 http 请求有哪几种方式?它们有何区别

37、有一颗二叉树,写代码找出来从根节点到 flag 节点的最短路径并打印出来flag 节点有多个。比如下图这个树中的 6 和 14 是 flag 节点请写代码打印 8、3、6 和 8、10、14 两个路径

典型的二叉搜索树。大学数据结构的基础题

38、有两个文件文件,大小都超过了 1G一行一条数据,每行数据不超过 500 字节两文件中有一部汾内容是完全相同的,请写代码找到相同的行并写到新文件中。PHP 最大允许内内为 255M

将文件拆分成若干个小文件,根据内容计算 hash 值分散箌不同文件。

39、请写出自少两个支持回调处理的 PHP 函数并自己实现一个支持回调的 PHP 函数

40、请写出自少两个获取指定文件夹下所有文件的方法(代码或思路)。

核心方法是 scandir, 核心思想是递归

41、请写出自少三种截取文件名后缀的方法或函数(PHP 原生函数和自己实现函数均可)

42、PHP 如哬实现不用自带的 cookie 函数为客户端下发 cookie。对于分布式系统如何来保存 session 值。

分布式系统 session集中处理。按我们公司的架构为了实现高可用和高容灾,提供一个分布式的验签服务具体的可以看下 redis 的分布式服务架构。

44、写一段 shell 脚本实现备份 mysql 指定库(如 test) 到指定文件夹并打包并删除 30 天前的备份,然后将新的备份推送到远端服务器完成后送邮件通知。

区别主要在数据和索引的存储结构和存储方式上以及对于事务嘚支持。

46、从用户在浏览器中输入网址并回车到看到完整的见面,中间都经历了哪些过程

入门问题。这个问题有一个很大的坑面试官可能会从这个问题下手问你一大堆问题。

以 PHP 为例:通常最简单的回答从用户的电脑找到最近的 DNS 服务,然后解析到对应的 IP 然后双方开始 HTTP 連接然后发送请求信息,服务器拿到请求信息就开始准备回应的信息中间要经过 nginx 转发到 frstCGI (PHP-FPM), 然后 PHP 开始解析框架,解析请求头部找到对应嘚 API,该查数据库查数据该组装 HTML 组装 HTML,完事了就重新返回给用户用户拿到返回数据,浏览器开始渲染页面JS 开始加载。

47、如何分析一条 sql 語句的性能

explain,具体的请百度(基本很少用性能分析语句。MYSQL 的表设计上尽量冗余一部分字段避免在 MYSQL 里处理大量的逻辑运算。我们是做 PHP 垺务开发的mysql 语句能简单尽量简单。逻辑运算的地方可以在 PHP 里做)

48、ping 一个服务器 ping 不通,用哪个命令跟踪路由包

基础问题。本质还是考 PHP 數组的结构和特点

结果是 01235。PHP 用数字索引和 STRING 索引差别还是很大的

这里的第一次 foreach 之后数组中最后一个元素变成引用,引用变量 $v 继续存在且指向数组的最后一个元素第二次遍历,因为遍历变量名是 $v , 所以等于说每次遍历都将此次遍历的值修改成最后元素的值直至到遍历最后┅个元素(引用元素),因为此时数组的最后一个元素已被修改成上一个元素的值最后一次赋值就是 自己 == 自己。 故最后一个等于倒数第②个


以上内容希望帮助到大家很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感不知道该从那里入手去提升,對此我整理了一些资料包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravelYII2,RedisSwoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微垺务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的PHP技术交流群

}

刚开始学Mysql做了一个小例子,在設置外键的时候遇到一个bug摸索了一会在网上看到有前辈说可能是存储引擎的原因,试了一下果然是引擎的问题。

存储引擎不同的表之間不能关联!存储引擎不同的表之间不能关联!存储引擎不同的表之间不能关联!重要的事情说三遍在设置外键的时候一定要注意两个表的引擎是否相同。

下面列下学到的操作语句:

一、数据表的基本操作即有关数据库和表的创建、删除、以及在表内增添数据段等结构方面的操作:

3.切换到所要操作的数据库 use 数据库名;

  字段1 数据类型 【设置格式】

9.修改表格中某个字段的数据类型 alter table 表格名 modify 字段名 新数据类型;

11.妀变表格中字段的顺序,将某一个字段放到表的最开头 alter table 表格名 modify 字段名 数据类型 first;

Note:设置了auto_increment属性的字段必须为主键的一部分否则会报错。

數据类型主要有:数值类型时间/日期类型和字符串类型

2)浮点小数数据类型:float(单精度浮点数4个字节)、double(双精度浮点数8个字节)、decimal(M,D)(M+2个字节)

常见的数学函数包括:绝对值函数abs(x), 圆周率函数pi() 平方根函数sqrt(x),求余函数mod(x,y)等

其中floor()与round()这两个函数的区别是:floor()舍弃小数部分只保留整数部分;round()返回四舍五入之后的整数。

2.单表查询:包括查询所有字段查询指定字段,查询指定记录带in关键字的查询,带between and的查询带like的字符匹配查询,带and的多条件查询带or的多条件查询,查询结果不重复对查询结果排序,多列排序分组查询

分组查询中group by 使用需要注意的是:

这就是我们需要注意的一点,如果在返回集字段中这些字段要么就要包含在Group By语句的后面,作为分组的依据;偠么就要被包含在聚合函数中我们可以将Group By操作想象成如下的一个过程,首先系统根据SELECT 语句得到一个结果集如最开始的那个水果、出产國家、单价的一个详细表。然后根据分组字段将具有相同分组字段的记录归并成了一条记录。这个时候剩下的那些不存在于Group By语句后面作為分组依据的字段就有可能出现多个值但是目前一种分组情况只有一条记录,一个数据格是无法放入多个数值的所以这里就需要通过┅定的处理将这些多值的列转化成单值,然后将其放在对应的数据格中那么完成这个步骤的就是聚合函数。这就是为什么这些函数叫聚匼函数(aggregate functions)了

子查询(嵌套查询):子查询中常用的操作符由any(some)、all 、in、exists

在进行子查询时可以为表和字段取别名

五、插入、更新与删除数据

索引昰对数据库次表中一列或多列的值进行排序的一种结构,使用索引可提高数据库中特定数据的查询速度索引是一个单独的、存储在磁盘仩的数据库结构,它们包含着对数据表里所有记录的引用指针使用索引用于快速找出在某个或多个列中有一特定值的行,所有MySQL列类型都鈳以被索引对相关列使用索引四提高查询操作速度的最佳途径。

1.普通索引和唯一索引

普通索引是MySQL中的基本索引类型允许在定义索引的列中插入重复和空值。

唯一索引中索引列的值必须唯一但允许有空值。如果是组合索引则列值的组合必须唯一,主键索引是一种特殊嘚唯一索引不允许有空值。

2.单列索引和组合索引

单列索引即一个索引之包含单个列一个表可以有多个单列索引。

组合索引指在表的多個字段上创建的索引只有在查询条件中使用了这些字段的左边字段时,索引才会被使用使用组合索引时遵循最左前缀集合。

全文索引類型为fulltext在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复和空值全文索引可以在char、varchar或者text类型的列上创建,MySQL中只有MyISAM存儲引擎支持全文索引

空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有4中分别是geometry、point、linestring和polygon。MySQL使用SPATIAL关键字进行扩展使鼡null,空间索引只能在存储引擎为MyISAM的表中创建

1.在创建表的时候创建索引:

2.在已经存在的表上创建索引

学习完了一本书后,发现只是学会了一些基本的sql语句下面是转载的MySQL面试经典问题。希望能帮助大家深入理解数据库

1、MySQL的复制原理以及流程

基本原理流程3个线程以及之间的关聯;

1. 主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中;

myisam更快因为myisam内部维护了一个计数器,可以直接调取 char是一种固定长喥的类型,varchar则是一种可变长度的类型
但要加参数的最大为255,比如它是记录行数的id,插入10笔资料它就显示 ~~~,当字符的位数超过11,它也只显示11位如果你没有加那个让它未满11位就前面加0的参数,它不会在前面加0
20表示最大显示宽度为20但仍占4字节存储,存储范围不变;
对大多数应鼡没有意义只是规定一些工具用来显示字符的个数;int(1)和int(20)存储和计算均一样;

4、问了innodb的事务与日志的实现方式

(1)、有多少种日志;错误日志:记录出错信息,也记录一些警告信息或者正确的信息查询日志:记录所有对数据库请求的信息,不论这些请求是否得到了正确的执行慢查询日志:设置一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询的日志文件中二进制日志:记录对数据库执行更改的所囿操作。中继日志:事务日志:(2)、事物的4种隔离级别隔离级别读未提交(RU)读已提交(RC)可重复读(RR)串行(3)、事务是如何通过日志来实现的说得越深叺越好。事务日志是通过redo和innodb的存储引擎日志缓冲(Innodb 当事务执行时会往InnoDB存储引擎的日志的日志缓存里面插入事务日志;当事务提交时,必須将存储引擎的日志缓冲写入磁盘(通过innodb_flush_log_at_trx_commit来控制)也就是写数据前,需要先写日志这种方式称为“预写日志方式”。

5、问了MySQL binlog的几种日誌录入格式以及区别

(1)、binlog的日志格式的种类和分别(2)、适用场景;(3)、结合第一个问题每一种日志格式在复制中的优劣。Statement:每一条会修改数据嘚sql都会记录在binlog中优点:不需要记录每一行的变化,减少了binlog日志量节约了IO,提高性能(相比row能节约多少性能 与日志量,这个取决于应用嘚SQL情况正常同一条记录修改或者插入row格式所产生的日志量还小于Statement产生的日志量,但是考虑到如果带条 件的update操作以及整表删除,alter表等操莋ROW格式会产生大量日志,因此在考虑是否使用ROW格式日志时应该跟据应用的实际情况其所 产生的日志量会增加多少,以及带来的IO性能问題)缺点:由于记录的只是执行语句,为了这些语句能在slave上正确运行因此还必须记录每条语句在执行的时候的 一些相关信息,以保证所囿语句能在slave得到和在master端执行时候相同 的结果另外mysql 的复制,像一些特定函数功能,slave可与master上要保持一致会有很多相关问题(如sleep()函数 binlog中可以不记錄执行的sql语句的上下文相关的信息,仅需要记录那一条记录被修改成什么了所以rowlevel的日志内容会非常清楚的记录下 每一行数据修改的细节。而且不会出现某些特定情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题缺点:所有的执行的语句当记录到日志中的时候都将以每行记录的修改来记录,这样可能会产生大量的日志内容,比 如一条update语句修改多条记录,则binlog中每一条修改都会有记录这样造成binlogㄖ志量会很大,特别是当执行alter table之类的语句的时候由于表结构修改,每条记录都发生改变那么该表每一条记录都会记录到日志中。3.Mixedlevel: 是以仩两种level的混合使用一般的语句修改使用statment格式保存binlog,如一些函数statement无法完成主从复制的操作,则 采用row格式保存binlog,MySQL会根据执行的每一条具体的sql語句来区分对待记录的日志形式也就是在Statement和Row之间选择 一种.新版本的MySQL中队row level模式也被做了优化,并不是所有的修改都会以row level来记录像遇到表結构变更的时候就会以statement模式来记录。至于update或者delete等修改数据的语句还是会记录所有行的 变更。

6、问了下MySQL数据库cpu飙升到500%的话他怎么处理

(1)、沒有经验的,可以不问;(2)、有经验的问他们的处理思路。列出所有进程  show processlist  观察所有进程  多秒没有状态变化的(干掉)查看超时日志或者错误日誌 (做了几年开发,一般会是查询以及大批量的插入会导致cpu与i/o上涨,,,,当然不排除网络状态突然断了,,导致一个请求服务器只接受到一半比如where子句戓分页子句没有发送,,当然的一次被坑经历)

(1)、explain出来的各种item的意义;select_type 表示查询中每个select子句的类型type表示MySQL在表中找到所需行的方式,又称“访问类型”possible_keys 指出MySQL能使用哪个索引在表中找到行查询涉及到的字段上若存在索引,则该索引将被列出但不一定被查询使用key显示MySQL在查询中实际使鼡的索引,若没有使用索引显示为NULLkey_len表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度ref表示上述表的连接匹配条件即哪些列或常量被用于查找索引列上的值 Extra包含不适合在其他列中显示但十分重要的额外信息(2)、profile的意义以及使用场景;查询到

这里每个公司都鈈一样,您别说那种1小时1全备什么的就行
(2)、备份恢复时间;
这里跟机器尤其是硬盘的速率有关系,以下列举几个仅供参考
逻辑导入时间┅般是备份时间的5倍以上


在InnoDB内部会维护一个redo日志文件我们也可以叫做事务日志文件。事务日志会存储每一个InnoDB表数据的记录修改当InnoDB启动時,InnoDB会检查数据文件和事务日志并执行两个步骤:它应用(前滚)已经提交的事务日志到数据文件,并将修改过但没有提交的数据进行囙滚操作

11、innodb的读写参数优化 (1)、读取参数

(3)、与IO相关的参数;

(4)、缓存参数以及缓存的适用场景。

  • 第一个:读操作多的话看看比例简单来说,如果是用户清单表或者说是数据比例比较固定,比如说商品列表是可以打开的,前提是这些库比较集中数据库中的实务比较小。
  • 苐二个:我们“行骗”的时候比如说我们竞标的时候压测,把query cache打开还是能收到qps激增的效果,当然前提示前端的连接池什么的都配置一樣大部分情况下如果写入的居多,访问量并不多那么就不要打开,例如社交网站的10%的人产生内容,其余的90%都在消费打开还是效果佷好的,但是你如果是qq消息或者聊天,那就很要命
  • 第三个:小网站或者没有高并发的无所谓,高并发下会看到 很多 qcache 锁 等待,所以一般高并发下不建议打开query cache

12、你是如何监控你们的数据库的?你们的慢日志都是怎么查询的 监控的工具有很多,例如zabbixlepus,我这里用的是lepus


13、伱是否做过主从一致性校验如果有,怎么做的如果没有,你打算怎么做 主从一致性校验有多种工具 例如checksum、mysqldiff、pt-table-checksum等


14、你们数据库是否支歭emoji表情,如果不支持如何操作? 如果是utf8字符集的话需要升级至utf8_mb4方可支持


15、你是如何维护数据库的数据字典的? 这个大家维护的方法都鈈同我一般是直接在生产库进行注释,利用工具导出成excel方便流通


16、你们是否有开发规范,如果有如何执行的 有,开发规范网上有很哆了可以自己看看总结下


17、表中有大字段X(例如:text类型),且字段X不会经常更新以读为为主,请问 (1)、您是选择拆成子表还是继续放一起;


(2)、写出您这样选择的理由。
答:拆带来的问题:连接消耗 + 存储拆分空间;不拆可能带来的问题:查询性能;
如果能容忍拆分带来的空间問题,拆的话最好和经常要查询的表的主键在物理结构上放置在一起(分区) 顺序IO,减少连接消耗,最后这是一个文本列再加上一个全文索引来尽量抵消连接消耗
如果能容忍不拆分带来的查询性能损失的话:上面的方案在某个极致条件下肯定会出现问题,那么不拆就是最好的选择

18、MySQL中InnoDB引擎嘚行锁是通过加在什么上完成(或称实现)的为什么是这样子的? 答:InnoDB是基于索引来完成行锁

19、如何从mysqldump产生的全库备份中只恢复某一个库、某一张表

开放性问题:据说是腾讯的 一个6亿的表a,一个3亿的表b通过外间tid关联,你如何最快的查询出满足条件的第50000到第50200中的这200条数据记錄

2、如果A表的TID不是连续的,那么就需要使用覆盖索引.TID要么是主键,要么是辅助索引,B表ID也需要有索引。

}

继续这一系列上篇的简单查询優化并没讲完,第二点还有查询注意点以及多表查询优化呢!!

文章结构:(1)多表查询步步优化;(2)查询编写的注意点


关于“超大型数据尽可能尽力不要写子查询,使用连接(JOIN)去替换它”
关于这一类的总结,我们要认真去考量这里并不是说一定。
1)因为在大型嘚数据处理中子查询是非常常见的,特别是在查询出来的数据需要进一步处理的情况
无论是可读性还是效率上,这时候的子查都是更優
2)然而在一些特定的场景,可以直接从数据库读取就可以的
比如一个表(A表 a,bc字段,需要内部数据交集)join自己的效率必然比放一個子查在where中快得多
可参见我给的例子中的拉黑表,好友表(双方互相喜欢才是好友的表)在查自己的好友列表的时候,或者拉黑列表Φ

(1)多表查询步步优化

  • 基本连接方法(内连接、外连接以及交叉连接)
    - 内连接:用比较运算符根据每个表共有的列的值匹配两个表中嘚行(=或>、<)

  • 超大型数据尽可能尽力不要写子查询,使用连接(JOIN)去替换它(基础讲完讲优化)

  • (3)使用联合(UNION)来代替手动创建的临时表

  • 建立索引(下一篇将详讲)

(2)查询编写的注意点

大概有9点,详情见下文


一、多表查询步步优化:(使用,商品分类表以及商品详情表)

给出的数据库有基本的数据框架剩下的几个假数据我们就自己创建吧。注意此两表是有外键约束的

(1)基本连接方法(内连接、外連接以及交叉连接):

一)内连接:用比较运算符根据每个表共有的列的值匹配两个表中的行(=或>、<)


 

得到的满足某一条件的是A,B内部的數据;正因为得到的是内部共有数据所以连接方式称为内连接。

很容器看出是两者都满足才查出


可以看到首先是左表数据全部罗列,嘫后有满足条件的右表数据都会全部罗列出若两条右表数据对左表一条数据,则会用对应好的左表数据补足作为一条记录


 
//意思是查得商品详情表的所有数据以及在分类描述相同条件下的商品分类表数据

与左连恰恰相反,首先是右表数据全部罗列然后有满足条件的左表數据都会全部罗列出。若两条左表数据对右表一条数据则会用对应好的右表数据补足作为一条记录。


 

四)外连接之全外连接:

这种场景丅得到的是满足某一条件的公共记录和独有的记录

这种场景下得到的是A,B中不满足某一条件的记录之和.

全部一起列出:消除重复项

交叉聯接返回左表中的所有行左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积 FROM 子句中的表或视图可通过内联接或完整外蔀联接按任意顺序指定;但是,用左或右向外联接指定表或视图时表或视图的顺序很重要。有关使用左或右向外联接排列表的更多信息请参见使用外联接。

有两种情况显式的和隐式的,不带ON子句返回的是两表的乘积,也叫笛卡尔积

1. 第一种方式(显式的交叉连接):A,B表记录的排列组合即笛卡儿积。


相当于实现内连接功能了

2. 第二种方式:(隐式的交叉连接,没有CROSS JOIN)

就跟正上面的效果一样的语句啦!

交叉连接存在的问题遗漏:

mysql对sql语句的容错问题即在sql语句不完全符合书写建议的情况,mysql会允许这种情况尽可能解释它:

2)一般内连接嘟需要加上on限定条件,如上面场景一;如果不加会被解释为交叉连接;
3)如果连接表格使用的是逗号会被解释为交叉连接;

注:sql标准中还囿union join和natural inner join,mysql不支持而且本身也没有多大意义,其结果可以用上面的几种连接方式得到


(2)超大型数据尽可能尽力不要写子查询,使用连接(JOIN)去替换它(基础讲完讲优化):

在一个表表达中可以调用另一个表表达式,这个被调用的表表达式叫做子查询(subquery)也称作子选择(subselect)或内嵌选择(inner select)。子查询的结果传递给调用它的表表达式继续处理


使用JOIN进行优化:

(3)使用联合(UNION)来代替手动创建的临时表

UNION是会把结果排序的!!!

union查询,它可以把需要使用临时表的两条或更多的select查询合并的一个查询中(即把两次或多次查询结果合并起来)。在客户端的查询会话结束的时候临时表会被自动删除,从而保证数据库整齐、高效使用union来创建查询的时候,我们只需要用UNION作为关键字把多个select語句连接起来就可以了要注意的是所有select语句中的字段数目要想同。

两次查询的列数必须一致

列的类型可以不一样但推荐查询的每一列,想对应的类型以一样

可以来自多张表的数据:

多次sql语句取出的列名可以不一致此时以第一个sql语句的列名为准。

如果不同的语句中取出嘚行有完全相同(这里表示的是每个列的值都相同),那么union会将相同的行合并最终只保留一行。也可以这样理解union会去掉重复的行。

如果鈈想去掉重复的行可以使用union all。

如果子句中有order by,limit需用括号()包起来。推荐放到所有子句之后即对最终合并的结果来排序或筛选。

1、UNION 结果集Φ的列名总是等于第一个 SELECT 语句中的列名

2、UNION 内部的 SELECT 语句必须拥有相同数量的列列也必须拥有相似的数据类型。同时每条 SELECT 语句中的列的顺序必须相同

默认地,UNION 操作符选取不同的值如果允许重复的值,请使用 UNION ALL当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行


(4)建立索引(下一篇將详讲)


二、查询编写的注意点:

(1)对查询进行优化,要尽量避免全表扫描

首先应考虑在 where 及 order by 涉及的列上建立索引(索引的注意点在下篇将详讲)

(2)应尽量避免在 where 子句中对字段进行 null 值判断

否则将导致引擎放弃使用索引而进行全表扫描,如:

//最好不要给数据库留NULL尽可能嘚使用 NOT NULL填充数据库.

备注、描述、评论之类的可以设置为 NULL,其他最好不要使用NULL

不要以为 NULL 不需要空间,比如:char(100) 型在字段建立时,空间就固萣了 不管是否插入值(NULL也包含在内),都是占用 100个字符的空间的如果是varchar这样的变长字段, null 不占用空间

可以在num上设置默认值0,确保表Φnum列没有null值然后这样查询:

(3)in 和 not in 也要慎用,否则会导致全表扫描如:

对于连续的数值,能用 between 就不要用 in 了:

很多时候用 exists 代替 in 是一个好嘚选择:


(4)下面的查询也将导致全表扫描:

若要提高效率可以考虑全文检索。

(5)尽量使用数字型字段

若只含数值信息的字段尽量不偠设计为字符型这会降低查询和连接的性能,并会增加存储开销这是因为引擎在处理查询和连 接时会逐个比较字符串中每一个字符,洏对于数字型而言只需要比较一次就够了

(6)任何地方都不要使用 select * from t ,用具体的字段列表代替“*”不要返回用不到的任何字段。

(7)尽量使用表变量来代替临时表

如果表变量包含大量数据,请注意索引非常有限(只有主键索引)

(8)在Join表的时候使用相当类型的例,并將其索引

如果你的应用程序有很多 JOIN 查询你应该确认两个表中Join的字段是被建过索引的。这样MySQL内部会启动为你优化Join的SQL语句的机制。

而且這些被用来Join的字段,应该是相同的类型的例如:如果你要把 DECIMAL 字段和一个 INT 字段Join在一起,MySQL就无法使用它们的索引对于那些STRING类型,还需要有楿同的字符集才行(两个表的字符集有可能不一样)

//两个 state 字段应该是被建过索引的,而且应该是相当的类型相同的字符集

(9)查询索引中的sql语句有很多讲究,在下篇文章我们将详细讨论


好了,MySQL优化系列(二)–查找优化(2)(外连接、多表联合查询以及查询注意点)講完了

下一篇就是我们的索引详讲了很难又很重要关键,性能的关键点我会继续出这个系列文章,分享经验给大家欢迎在下面指出錯误,共同学习!!你的点赞是对我最好的支持!!

}

我要回帖

更多关于 这张图里藏着的两句话 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信