卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章64334本站已运行4115

如何写出高性能SQL

定量遍历次数

在撰写一条查询语句的时候,可以依据你必须查询数据表的数据总量,估算一下这条查询大致需要结点多少行数据:

如果结点行数在百万以内的,只要不是每秒钟都要继续执行几十上百次的频密查询,可以指出就是安全的。

遍历数据行数在几百万的,查询时间最少也要几秒钟,你就要认真考虑有没有优化的办法。

结点行数达至千万量级和以上的,我只能说你,这种查询就不必须发生在你的系统中。当然我们这里说道的都就是在线交易系统,离线分析类系统另说。

遍历行数在千万左右,就是 MySQL 查询的一个坎儿。MySQL 中单个表数据量,也必须尽量掌控在一千万条以下,最多不要少于二三千万这个量级。原因也较好理解,对一个千万级别的表中继续执行查询,加上几个 WHERE 条件过滤一下,符合条件的数据最多可能在几十万或者百万量级,这还可以接受。但如果再和其他的表做一个联手查询,结点的数据量很可能就少于千万级别了。所以,每个表的数据量最出色大于千万级别。

避免全表索引

绝大多数情况下,我们编写的查询语句,都必须使用索引,防止去遍历整张表,也就是通常说的,防止全表扫描。你在每次开发新功能,需要给数据库减少一个新的查询时,都要评估一下,是不是存有索引可以提振代莱查询语句,如果有必要的话,须要新建索引去积极支持追加的查询。

减少索引代价的代价就是,会降低数据填入、删掉和更新的性能。这个也较好认知,增加了索引,在数据变化的时候,不仅必须变更数据表里的数据,还要去变更每个索引。所以,对于更新频繁并且对更新性能要求较低的表,可以尽量少建好索引。而对于查询较多更新较少的表,可以根据查询的业务逻辑,适度多建一些索引。

分析 SQL 继续执行计划

在 MySQL 中使用继续执行计划也非常简单,只要在你的 SQL 语句前面加之 EXPLAIN 关键字,然后执行这个查询语句就可以了。

比如说有一个用户表中,包含用户 ID、姓名、部门编号和状态这几个字段:

我们期望查询某个二级部门下的所有人,查询条件就是,部门代号以 00028 开头的所有人。下面这两个 SQL,他们的查询结果是一样的,都满足要求,但是,哪个查询性能更好呢?

SELECT * FROM user WHERE left(department_code, 5) = '00028';SELECT * FROM user WHERE department_code LIKE '00028%';

我们分别查看一下这两个 SQL 的继续执行计划:

row 列于:

MySQL 预估执行这个 SQL 可能会结点的数据行数。第一个 SQL 遍历了四千多行,这就是整个 User 表的数据条数;第二个 SQL 只有 8 行,这 8 行其实就是符合条件的 8 条记录。似乎第二个 SQL 查询性能要远远好于第一个 SQL。

type 列于:

则表示这个查询的出访类型。ALL 代表全表读取,这是最差的情况。range 代表使用了索引,在索引中进行范围查找,因为第二个 SQL 语句的 WHERE 中有一个 LIKE 的查询条件。如果轻易命中索引,type 这一列表明的就是 index。如果采用了索引,可以在 key 这一列中看到,实际上使用了哪个索引。

总结

在开发阶段,衡量一个 SQL 查询语句查询性能的手段是,估算继续执行 SQL 时须要遍历的数据行数。结点行数在百万以内,可以认为是安全的 SQL,百万到千万这个量级则须要认真评估和优化,千万级别以上则是非常危险的。为了增加慢 SQL 的可能性,每个数据表的行数最好控制在千万以内。 索引可以显著增加查询遍历数据的数量,所以提升 SQL 查询性能最有效的方式就是,使查询尽可能多的命中索引,但索引也就是一把双刃剑,它在提升查询性能的同时,也可以减少数据更新的性能。 对于繁杂的查询,最出色使用 SQL 继续执行计划,事先对查询做一个分析。在 SQL 执行计划的结果中,可以看到查询预估的结点行数,击中了哪些索引。执行计划也可以很好地帮助你优化你的查询语句。

卓越飞翔博客
上一篇: MySQL安装教程
下一篇: 最新php蓝奏云直链api接口源代码
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏