SQL面试总结

2023-05-16

一、 查询性能优化

1. 使用 Explain 进行分析

Explain 用来分析 SELECT 查询语句,开发人员可以通过分析 Explain 结果来优化查询语句。

比较重要的字段有:

  • select_type : 查询类型,有简单查询、联合查询、子查询等

  • key : 使用的索引

  • rows : 扫描的行数


mysql> explain select * from user_info where id = 2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user_info
   partitions: NULL
         type: const
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 8
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)  

更多内容请参考:MySQL 性能优化神器 Explain 使用分析

2. 优化数据访问

1. 减少请求的数据量

(一)只返回必要的列

最好不要使用 SELECT * 语句。

(二)只返回必要的行

使用 WHERE 语句进行查询过滤,有时候也需要使用 LIMIT 语句来限制返回的数据。

(三)缓存重复查询的数据

使用缓存可以避免在数据库中进行查询,特别要查询的数据经常被重复查询,缓存可以带来的查询性能提升将会是非常明显的。

2. 减少服务器端扫描的行数

最有效的方式是使用索引来覆盖查询。

3. 重构查询方式

1. 切分大查询

一个大查询如果一次性执行的话,可能一次锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞很多小的但重要的查询。


DELEFT FROM messages WHERE create < DATE_SUB(NOW(), INTERVAL 3 MONTH);  

rows_affected = 0
do {
    rows_affected = do_query(
    "DELETE FROM messages WHERE create  < DATE_SUB(NOW(), INTERVAL 3 MONTH) LIMIT 10000")
} while rows_affected > 0  

2. 分解大连接查询

将一个大连接查询(JOIN)分解成对每一个表进行一次单表查询,然后将结果在应用程序中进行关联,这样做的好处有:

  • 让缓存更高效。对于连接查询,如果其中一个表发生变化,那么整个查询缓存就无法使用。而分解后的多个查询,即使其中一个表发生变化,对其它表的查询缓存依然可以使用。

  • 分解成多个单表查询,这些单表查询的缓存结果更可能被其它查询使用到,从而减少冗余记录的查询。

  • 减少锁竞争;

  • 在应用层进行连接,可以更容易对数据库进行拆分,从而更容易做到高性能和可扩展。

  • 查询本身效率也可能会有所提升。例如下面的例子中,使用 IN() 代替连接查询,可以让 MySQL 按照 ID 顺序进行查询,这可能比随机的连接要更高效。


SELECT * FROM tab
JOIN tag_post ON tag_post.tag_id=tag.id
JOIN post ON tag_post.post_id=post.id
WHERE tag.tag='mysql';
SELECT * FROM tag WHERE tag='mysql';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904);  

二、最左匹配原则的底层原理

最左匹配原则都是针对联合索引来说的,所以我们可以从联合索引的原理来了解最左匹配原则。

我们都知道索引的底层是一颗 B+ 树,那么联合索引当然还是一颗 B+ 树,只不过联合索引的键值数量不是一个,而是多个。构建一颗 B+ 树只能根据一个值来构建,因此数据库依据联合索引最左的字段来构建 B+ 树。例子:假如创建一个(a,b,c)的联合索引,那么它的索引树是这样的:

 

该图就是一个形如(a,b,c)联合索引的 b+ 树,其中的非叶子节点存储的是第一个关键字的索引 a,而叶子节点存储的是三个关键字的数据。这里可以看出 a 是有序的,而 b,c 都是无序的。但是当在 a 相同的时候,b 是有序的,b 相同的时候,c 又是有序的。通过对联合索引的结构的了解,那么就可以很好的了解为什么最左匹配原则中如果遇到范围查询就会停止了。以 select * from t where a=5 and b>0 and c =1; #这样a,b可以用到(a,b,c),c不可以 为例子,当查询到 b 的值以后(这是一个范围值),c 是无序的。所以就不能根据联合索引来确定到底该取哪一行。

总结

在 InnoDB 中联合索引只有先确定了前一个(左侧的值)后,才能确定下一个值。如果有范围查询的话,那么联合索引中使用范围查询的字段后的索引在该条 SQL 中都不会起作用。值得注意的是,in 和 = 都可以乱序,比如有索引(a,b,c),语句 select * from t where c =1 and a=1 and b=1,这样的语句也可以用到最左匹配,因为 MySQL 中有一个优化器,他会分析 SQL 语句,将其优化成索引可以匹配的形式,即 select * from t where a =1 and b=1 and c=1

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL面试总结 的相关文章

  • postgresql:插入...(选择*...)

    我不确定它是否是标准 SQL INSERT INTO tblA SELECT id time FROM tblB WHERE time gt 1000 我正在寻找的是 如果 tblA 和 tblB 位于不同的数据库服务器中怎么办 Postg
  • 如何拥有引用另一个表的检查约束?

    我在 SQL Server 2008 数据库中有以下表 tblItem 其中有一个ItemID field 好项目 它还有一个 ItemID 字段 并且有一个指向 tblItem 的外键 tblBadItem 它也有一个 ItemID 字段
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 获取mysql中逗号分隔行中不同值的计数

    一个表 Jobs 有 2 列 JobId 城市 当我们保存工作时 工作位置可能是多个城市 如下所示 JobId City 1 New York 2 New York Ohio Virginia 3 New York Virginia 我如何
  • MySQL“列计数与第 1 行的值计数不匹配”是什么意思

    这是我收到的消息 ER WRONG VALUE COUNT ON ROW 列计数与第 1 行的值计数不匹配 这是我的全部代码 我的错误在哪里 DROP TABLE student CREATE TABLE employee emp id I
  • 查看Jasper报告执行的SQL

    运行 Jasper 报表 其中 SQL 嵌入到报表文件 jrxml 中 时 是否可以看到执行的 SQL 理想情况下 我还想查看替换每个 P 占位符的值 Cheers Don JasperReports 使用 Jakarta Commons
  • 总和和不同不会改变结果?

    我是一个新手 试图在这里解决这个问题 到目前为止还没有运气 非常感谢任何帮助 Select Distinct AB agency no ab branch no AS AGENCY BRANCH count AB agency no ab
  • 消息 203,级别 16,状态 2,不是有效标识符

    我收到以下错误 消息 203 级别 16 状态 2 过程 getQuestion 第 18 行名称 select top 1 from tlb Question inner join tlb options on tlb options q
  • 如何对 SQL 进行多次查询

    我正在尝试创建一个表 并在 PHP 脚本的帮助下在数据库中插入一些值 虽然只插入 1 行 但效果很好 当我尝试输入更多行数时 出现错误 我需要为每个查询编写完整的插入语句 因为我正在使用在线 Excel 到 SQL 查询转换器
  • 如何将今天的日期返回到 Oracle 中的变量

    我想做这个 DECLARE today as smalldatetime SELECT today GetDate 但我需要一个oracle翻译 甲骨文使用SYSDATE 还有 ANSI 标准CURRENT TIMESTAMP 除其他外 S
  • 随着时间的推移累积(不重叠)——技术?

    我正在尝试找到一种更好的方法来制作水晶报告 其他人的 按组添加不重叠的时间 这显然是一个古老的问题 有没有一种技术可以得到 调整每条记录的 开始 结束 时间 以消除共同 重叠时间 亚组内 使用直接 SQL 尽管我发现我可以执行 CTE 假设
  • SKIP加锁和nowait的区别

    pl sql 中 SKIP 锁定游标和 nowait 游标之间的区别 我认为我找到的这张图片是描述差异的最佳例子 详细说明 http viralpatel net blogs oracle skip locked
  • 从表中选择行,其中另一个表中具有相同 id 的行在另一列中具有特定值

    在 MySQL 中 如果我们有两个表 comments key value 1 foo 2 bar 3 foobar 4 barfoo and meta comment key value 1 1 2 1 3 2 4 1 我想得到来自以下人
  • 在 Yii 的标准中如何获得计数 (*)

    我正在尝试构建一个具有以下内容的查询group by属性 我正在尝试得到id和count它一直告诉我count is invalid列名 我怎样才能得到count来自group by询问 工作有别名 伊伊 1 1 11 其他不及格 crit
  • Oracle SQL PLS-00049:错误的绑定变量

    我收到此错误 这似乎是列拼写问题 然而 我 99 确信我拼写的所有内容都是正确的 但我看不出有任何理由会出现我所犯的错误 这是来源 CREATE OR REPLACE TRIGGER update qoh trigger AFTER INS
  • 使用函数的 SQL 查询 - 如何获取列表的最大计数

    如何查询 MAXIMUM COUNT 交易次数 我的代码如下 SELECT customer id COUNT customer id FROM rental GROUP BY customer id HAVING MAX COUNT cu
  • SQL Server:如果存在会大大减慢查询速度

    正在使用SQL Server 2012 我找到了一些关于查询优化的主题 并将 EXISTS 与 COUNT 进行比较 但我找不到这个确切的问题 我有一个看起来像这样的查询 select from tblAccount as acc join
  • CONTAINS 不适用于 Oracle Text

    我在执行此查询时遇到问题 SELECT FROM gob attachment WHERE CONTAINS gob a document java gt 0 它给了我 ORA 29902 error in executing ODCIIn
  • 为什么 ISNUMERIC('.') 返回 1?

    最近我在 SQL Server 中使用 ISNUMERIC 时遇到了一个问题 导致找到了这段代码 SELECT ISNUMERIC 这会返回 1 如 true 所示 难道不应该像 false 一样返回 0 吗 See Numeric 损坏了
  • 替换字符串中的多个字符,而不使用任何嵌套替换函数

    我的表中存储了一个方程 我一次获取一个方程 并希望将所有运算符替换为任何其他字符 输入字符串 N 100 6858 6858 N 100 0 2 N 35 运算符或模式 替换字符 输出字符串 N 100 6858 6858 N 100 0

随机推荐

  • Error: This command has to be run with superuser privileges (under the root user on most systems).

    意思是错误 xff1a 此命令必须以超级用户权限 xff08 在大多数系统上以root用户权限 xff09 运行 所以当前的用户是普通用户 xff0c 需要切换为超级用户 xff08 root用户 xff09 先输入在命令行中输入 su r
  • P200 7

    lt img src 61 34 https img blog csdn net 20150518130711865 watermark 2 text aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWXVTb25nNDg2OQ 6
  • 设计一个支持多版本的APP的后端服务

    以注册为例子的说明 我们以我们的用户中心的注册为例子我们实现的非常简单就是做一个校验 xff0c 校验成功之后 xff0c 把用户注册的数据入库即可 随着我们产品的迭代注册肯定没有这么简单 比如说我需要填写一个电话号码并且拿到验证码并验证正
  • 嵌入式工程师“中年危机”应对策略上

    嵌入式工程师 中年危机 的问题 xff08 这是个普遍现象 xff09 xff0c 当然 xff0c 面向对象不只是程序猿 众所周知 xff0c 钱 是个好东西 xff0c 能帮你解决90 的烦恼 xff0c 剩下的10 当然也可以用这东西
  • ROS实现串口解析GPS协议,并发布到话题

    1 串口配置 ROS串口编程学习笔记 xff1a https blog csdn net u014695839 article details 81209082 ROS系统的串口数据读取和解析 xff1a https blog csdn n
  • python3中input()回车不结束,改为另起一行

    参照 lst 61 while True x 61 input if len x 61 61 0 break lst append x upper for line in lst print line
  • 使用STM32 ST-LINK Utility 烧录程序,ST LINK烧录程序,解锁FLASH

    关键词 xff1a ST LINK烧录程序 xff0c STLINK烧录程序 xff0c ST LINK烧录程序 xff0c STLINK烧录程序 xff0c ST LINK解锁Flash 1 读取STM32内部FLASH及芯片信息 使用S
  • 串口调试助手,串口监控,虚拟示波器,串口示波器,网络调试工具 网络抓包监控 Wireshark.

    嵌入式开发工具收集 目录 嵌入式开发工具收集 1 串口调试工具 xff1a Xshell 6 2 串口调试工具 xff1a 界面炫 xff0c 开源软件 MobaXterm Portable v20 6 3 串口虚拟示波器1 xff1a D
  • 小米2020校招软件开发工程师笔试题一

    1 下列关于设计模式说法错误的是 xff08 B xff09 A 装饰器模式在实现过程中一般不会更改被封装对象的接口定义 B 适配器模式以不改变被适配对象的接口定义为目的对其进行改造 C 用饿汉方式实现的单例模式是不能够被继承的 D 简单工
  • 使用STM32与MAX30102实现的较为稳定的血氧算法

    现阶段网络上的算法读出的血氧值较为不稳定 xff0c 且许多情况下无法得出有效值 xff0c 本算法的原理见 xff1a MAX30102 血氧调试笔记 Yulong u012183892 CSDN博客 max30102 为了控制传感器采样
  • 通过代码测试算法的性能--以排序算法为例

    我们编写一个计算 xff08 算法执行时间 xff09 的函数来测试算法的性能 xff0c xff08 即本文性能把算法执行时间的长短作为标准 xff09 这里以排序函数为例作为被测函数 include lt iostream gt inc
  • Javascript 和vue使用for in 遍历array,取值和类型差异

    1 xff0c Javascript 使用for in 遍历 Array 在 Javascript 中是一个对象 xff0c Array 的索引是属性名 此处输出的索引值 xff0c 即 0 1 2 不是 Number 类型的 xff0c
  • 一文通俗搞懂线性无关特征向量个数≤特征值重数

    线代有个很难理解的知识点 xff0c 即同一特征值的线性无关特征向量个数要小于等于特征值重数 这个结论是怎么来的呢 xff1f 本文用最朴素的证明来帮助大家弄懂这个知识点 xff08 结论推导所用的都是基础的线代知识 xff0c 只是有些数
  • fatal: The remote end hung up unexpectedly解决方案

    在使用 git 更新项目时遇到了这句报错信息 xff1a fatal The remote end hung up unexpectedly 尝试了以下两种方法 xff1a 修改缓存大小 git config global http pos
  • STM32 BLDC无刷直流电机 HALL霍尔硬件接口 程序

    这里是使用STM32F103系列 xff0c 其他型号可能略有区别 设置步骤 xff1a 1 首先HALL的IO口初始化 2 硬件HALL接口初始化 3 检测到hall信号变化会触发TIM5中断 xff0c 中断处理进行电机换向 重点分析
  • 使用vscode的git工具

    当下很多ide都用对应的git工具 xff0c 这里介绍一下vscode的 在初始页面 xff0c 能看到有克隆git存储库选项 xff0c 选择后输入URL就开始克隆克隆后新建一个html文件来进行测试 选中git工具区 xff0c 这里
  • 开源netconf

    我们是基于libnetconf开源软件 xff08 https github com CESNET libnetconf xff09 进行二次开发 github中有两套libnetconf xff0c 一套是libnetconf xff0c
  • IMU原理

    惯性测量单元 xff08 IMU xff09 通常指由3个加速度计和3个陀螺仪组成的组合单元 xff0c 加速度计和陀螺仪安装在互相垂直的测量轴上 低精度的IMU可以通过其他方式修正 xff0c GPS用于修正位置的长期漂移 xff0c 气
  • 浪潮服务器NF5280M5配置管理口IP web界面登录 ipmi 代外【详细】

    开启服务器以后等待按del或f2 xff0c 进入bios选择第五项Server Mgmt界面选择BMC Network Configuration 回车 选择BMC IPv4 Network Configuration 回车 注意 只需要
  • SQL面试总结

    一 查询性能优化 1 使用 Explain 进行分析 Explain 用来分析 SELECT 查询语句 xff0c 开发人员可以通过分析 Explain 结果来优化查询语句 比较重要的字段有 xff1a select type 查询类型 x