ITPub博客

首页 > 数据库 > 数据库开发技术 > SQL优化思想②--让SQL跑得更慢一些!

SQL优化思想②--让SQL跑得更慢一些!

原创 数据库开发技术 作者:梁敬彬 时间:2024-10-30 08:01:49 0 删除 编辑



SQL优化思想系列

SQL优化思想⓵--不优化或许是最好的优化!


SQL优化思想⓶--让SQL跑得更慢一些!

引言

我们常常追求"让SQL跑得更快"。然而,L老师最近的举动颠覆了这一传统观念。他特意 让部分SQL运行得更慢,却 大幅提升了YYY平台的整体性能。这一反常操作立即引发了大家的好奇,纷纷向他请教其中奥妙。

是的, 从全局出发,适当地让部分SQL慢下来,有时还真是对的。

原本我计划直接讲解SQL优化的方法论, 但鉴于这一思想很有启发性,能对后续整体方法论的理解形成铺垫, 因此插入此集。 接下来,让我们进入正文。

0

没听错,让SQL跑得 更慢一些!

Q:L老师,听说您为YYY平台优化时,特意 让一部分SQL的跑的更慢一些,这是真的吗?
L:哈哈,是真的。
M:这听起来很 反直觉啊。
L: 引入并行,你快他慢;增加索引,查快写慢;关闭日志,险中求快。
众人面面相觑:啥,没听懂。
L:嗯,我会细细展开。其实SQL优化最要的是要有 整体意识,不能拘泥于局部的得失。接下来, 我就以YYY平台的A,B,C 模块为例,讲讲这背后的道理。

Q:期待!

1

案例1:引入并行,你快他慢!

L:首先说说A模块,我发现部分SQL设置了极高的 并行度,初衷是提速。结果,这条SQL确实运行得很快,可惜整个系统的响应时间反而变长,语句类似如下。

-- 在大表上使用并行度执行查询
SELECT /*+ PARALLEL(t, 16) */
COUNT(*)
FROM t_large_table t
...


Q:为什么会这样?

L:高并行度意味着更多的CPU和内存资源被单个查询所占用。在资源有限的环境中,这种做法会 抢占其他SQL所需的资源,导致整体系统的吞吐量下降。 优化不仅是提升某一条SQL的性能,更是要平衡系统中各个部分的资源分配。

随后我取消了该SQL的并行度,虽然其执行速度有所放慢,但释放出来的系统资源可以被其他关键SQL所利用,提升整个系统的稳定性和响应速度。这是一种“以慢带快”的优化思路。

W:明白了,资源总是有限的,需要合理分配。

L:确实如此。这让我想起了战国时期的"围魏救赵"策略。当时,魏国大举进攻赵国,动用了大部分兵力,以至于留守本土的军队不多。齐国并没有直接派兵支援赵国,而是攻打魏国本土。迫使魏军撤回攻赵的大军,最终赵国获救。这与我们的SQL优化有异曲同工之妙,都是利用资源有限的道理,通过调整分配来达成目的。

W:哈哈,并行SQL和围魏救赵,真有几分相似!


2


案例2:增加索引,查快写慢!
L:再说说B模块。该业务关键且繁忙,为提升查询速度,团队在表上添加了大量索引。结果 查询速度果然提升,但 写入性能却大幅下降,导致入库延迟,影响了业务,语句类似如下。
-- 添加多个索引
CREATE INDEX idx_1 
ON t1 (c1);
CREATE INDEX idx_2 
ON t1 (c2);
CREATE INDEX idx_3 
ON t1 (c3);
CREATE INDEX idx_4 
ON t1 (c4);
CREATE INDEX idx_5 ON t1 (c5);
...
-- 从另一个表批量插入数据
INSERT INTO t1
SELECT * 
FROM t2
WHERE...

Q:为什么添加索引会导致写入变慢?

L:数据库在执行更新操作时,不仅要修改数据本身,还需 同步更新所有相关的索引。这增加了额外的I/O开销, 表更新的频率越高,性能影响越明显。我们 需要根据实际的读写需求进行权衡。定期审查和优化现有索引,确保它们真正为业务需求服务,而不是盲目追求查询速度。
W:看来,考虑问题需要全面啊。

L:是的。这让我想起三国时期的街亭之战。马谡将军队驻扎在山上,只考虑了居高临下的优势,却忽视了缺水、补给困难和易受火攻的问题。结果被敌军切断补给并纵火,导致惨败。这与盲目增加索引很相似,专注于提高查询速度,却忽视了写入性能下降等其他重要因素。两者都是因为过于关注单一优势,而忽视了全局考虑。

X:可惜,要是 马谡读了《收获,不止SQL优化》,也不至于如此啊。

3

案例3:关闭日志,险中求快!

L:最后看看C模块,该团队为提升更新速度,关闭了部分表的日志记录。虽然更新性能显著提升,但这也意味着一旦系统崩溃,数据恢复几无可能,语句类似如下。
-- 关闭日志记录(谨慎使用,仅为演示)
ALTER TABLE t1 NOLOGGING;
-- 执行批量插入操作
INSERT /*+ APPEND */ INTO t1 (c1, c2, c3)
SELECT c1, c2, c3
FROM t2
where ...

Q:关闭日志真的能带来显著的性能提升?

L:确实, 关闭日志会减少I/O操作,尤其是在频繁的写操作中,性能提升明显。然而,日志是保障数据一致性和可恢复性的关键。 关闭日志虽然短期内提升了性能,但长远来看,数据的 安全性和可靠性遭到了严重威胁。
X:必须要在性能与安全之间找到平衡。
L:是的。这让我想起古代战争中的一个权衡。轻装上阵的士兵行军速度快,机动性强,就像关闭日志后的数据库操作。但他们在战斗中极易受伤,一旦遇到强敌就可能全军覆没。相比之下,穿戴重甲的士兵虽然行动缓慢,但在激烈的战斗中能够更好地保护自己,就像开启日志的数据库能在意外情况下恢复数据。
W :有趣,关闭日志就像抛弃盔甲,轻松一刻,危险长存。

结语

让SQL跑得慢一点来优化系统的相关案例远不止以上三个,比如“ 二十年目睹怪现状 ”提到的 缓存内存 、“ 二十年前的回忆 ”提到的 物化视图 等都是类似的,限于篇幅,就不展开了。如果让大家觉得意犹未尽,敬请谅解。

我们都知道,提升SQL速度能 节约成本、增强系统稳定性和改善用户体验,但更重要的是,我们需要具备 整体性思维, 注重平衡系统资源、数据安全与读写性能。过度追求速度,可能掏空资源、降低数据安全性。 因此,找到平衡点至关重要。有时,让SQL慢一点,反而是更高明的优化!

当然,对特定的SQL任务,也有不同取舍。如果 某些查询尤为关键 ,添加 并行 处理或许是 最佳方案 ;若 查询需求远大于写入 ,加 索引 或许 无妨 ;而若某些表 本身数据临时性强 , 关闭日志也是 合理 选择 。

兵无常势,水无常形。SQL优化如此,做人做事亦如此。 唯有具备全局视角,方能实 现 真正的成功。




未完待续...

公众号:收获不止数据库

微信:ljbyxl1213

系列回顾





原文作者:收获不止数据库;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论
历任中电福富研究院副理事长、中盾安信研究院副院长、宁德时代技术顾问等职务,受聘电信集团专家和国家十四五课题负责人,著有《收获,不止Oracle》《收获,不止SQL优化》等多本畅销数据库技术书籍。

注册时间:2024-02-06

  • 博文量
    162
  • 访问量
    198088