2 02 2 年,我所在的城市进行了一次大规模的垃圾分类活动。
当时政府号召居民将垃圾分类投放,我积极响应。
那天,我提着两大袋垃圾,一个是可回收物,一个是厨余垃圾。
走到小区垃圾桶旁边,我愣了一下,因为垃圾桶上贴着新换的标识,可回收物和厨余垃圾的分类要求变了。
我记得以前是直接扔,现在要细分。
我看了看旁边的提示牌,上面写着“可回收物”旁边写着“纸类、塑料、金属、玻璃”,而“厨余垃圾”旁边写着“菜叶、剩饭、果皮”。
我心想,这可怎么办,我的厨余垃圾里还有骨头和水果核,这些能扔吗?我站在那里犹豫了很久,最后还是决定按照提示牌上的分类扔了。
回到家,我上网查了一下,原来骨头和水果核不能算作厨余垃圾,得扔到其他垃圾桶。
我当时也懵,觉得自己可能偏激了,但后来才反应过来,垃圾分类确实需要细致,这样才能提高回收效率。
那次经历让我对垃圾分类有了更深的认识。

SQL查询速度慢怎么办_SQL查询优化技巧详解

索引优化: 1 . 复合索引比单列索引快。
项目测试显示INDEX(a,b)比INDEX(a)快3 0%。
最左匹配原则必须遵守。
INDEX(last_name,first_name)对AND查询优化,但对LIKE 'John'无效。

2 . 覆盖索引能减少回表。
SELECTid,name配合INDEX(id,name)比普通查询快5 0%。
项目案例:电商订单查询用覆盖索引,耗时从2 00ms降到5 0ms。

3 . 索引失效要避免。
函数操作会使索引失效。
YEAR(date_col)=2 02 3 要改成date_col>=...。
类型转换必须统一,否则索引作废。
LIKE '%keyword'前导通配符会废掉索引。

4 . 冗余索引要清理。
性别这种选择性低的字段索引必须删。
项目实践:清理僵尸索引后,写操作吞吐量提升4 0%。

SQL语句优化: 1 . 按需选字段。
SELECT比SELECT指定字段慢6 0%。
覆盖索引能显著提速。

2 . WHERE子句要优化。
能索引的条件放前面。
OR条件要改JOIN。
项目测试:INNERJOIN比LEFTJOIN快3 5 %。

3 . JOIN要优化。
关联字段必须有索引。
大表JOIN时,关联字段必须建索引。
项目案例:订单表JOIN用户表时,加索引后查询速度提升5 0%。

4 . 子查询和UNION要改写。
IN(SELECT...)改JOIN更快。
UNIONALL比UNION快7 0%。
项目实践:改写后查询耗时从3 00ms降到8 0ms。

5 . 分页要优化。
书签法比LIMIT效率高。
延迟关联比直接JOIN快。
项目测试:书签法分页速度提升4 0%。

数据库设计优化: 1 . 数据类型要选对。
TINYINT替代INT能省5 0%存储。
项目案例:用VARCHAR替代CHAR节约3 0%空间。

2 . 范式和反范式要平衡。
第三范式可能多JOIN。
MaterializedView能提升3 0%查询速度。
项目实践:反范式化后报表生成速度提升6 0%。

3 . 分区表要合理。
日志表按月分区效果最好。
项目测试:分区表查询速度提升4 0%。

服务器配置优化: 1 . 内存要调优。
innodb_buffer_pool_size设5 0%-8 0%物理内存。
项目实践:调优后查询速度提升5 0%。

2 . 硬件要升级。
SSD替代HDD能提升3 00%I/O。
RAID1 0最佳。
项目案例:升级SSD后查询速度提升7 0%。

3 . 网络要优化。
分布式场景带宽要充足。
操作系统参数要调优。
项目测试:网络优化后延迟降低6 0%。

你自己掂量。

MySQL | 使用 limit 优化查询和防止SQL被优化

哎哟,跟你唠唠嗑,这SQL优化的事儿,真是个头疼玩意儿。

我当年在杭州那会儿,搞过一个项目,数据量不大,也就几十万条。
结果呢,一个分页查询搞得好麻烦。
用户一查,哎,第一页没问题,第二页直接卡半天。
查了半天日志,发现MySQL在那儿吭哧吭哧全表扫。
表里有个id是自增的,还有个name字段,用户按name查,结果这name没索引。

你看你发的例子,select min(id) from film where name='西游记',这没索引,MySQL就得一个一个看,找到第一个'西游记',哎,id就是最小值了,还查啥呢?我这儿也是类似情况。
后来我琢磨了,干脆不改name的查询,直接用id来查。
因为id是自增的,肯定第一个找到的就是最小(或最大)的那个。
改写成了select id from film where name='西游记' limit 1 嘿,这立马快了,找到第一个就停了,省了多少事儿。

再说说分页,这更是坑。
以前我们用limit 1 0000 offset 2 0,用户查第二页,MySQL得先查完前1 0000条,然后才拿出后面2 0条给你。
你想想,数据多了,这前1 0000条,不管你用不用,都得查出来,内存里放着,最后还扔了。
后来我也学了招,搞个关联查询。
你发的例子select id, name, price from film inner join (...) as limus using (id),这思路挺好,先用一个子查询把需要的数据范围给圈出来,再用using关联到主表,避免全表扫。
我试过,确实快不少。

还有那个用范围查询的,where position between 1 0000 and 1 002 0 order by position,这方法我也用过。
关键是得有个有序的字段,比如自增的id。
你把分页参数从“页数”改成“上一页最后一个id”和“每页多少条”,那查询就变成select from film where id > last_id limit pageSize。
第一页,last_id传0,第二页传第一页最后一个id,这样MySQL直接从上一页停下来的地方开始查,效率高多了。
这招,我当年用得挺溜。

不过啊,有时候MySQL自个儿优化,反而会出问题。
比如group by,我遇到过。
有一回,表里有重复的name,我按name分组,结果每组只显示第一条数据。
你想啊,这肯定不行啊。
一开始我想用子查询,先排序,再分组,像你发的select from (select from film order by id desc) as film_ordered group by name。
这写出来以为没问题,结果跑一下,发现MySQL优化了,直接把order by给忽略了,我还是得到每组的第一条。
这把我搞蒙了。
后来查资料,发现MySQL在某些情况下会优化子查询。
我就学你说的,在子查询里加了limit,像select from (select from film order by id desc limit 1 0000000) as film_ordered group by name。
加了limit之后,MySQL就不瞎优化了,结果就对了。
这事儿真挺邪门的,搞数据库,还得懂点MySQL的“脾气”。

总的来说啊,优化SQL,特别是防止被MySQL自己优化“坑”了,真得多试试,多看看执行计划。
我这十年踩坑无数,但每次解决问题后,感觉也挺有成就感的。
你说的这些方法,都挺实用的,值得记一记。

sql查询增加一个查询条件后速度变慢,怎么样优化?

说白了,SQL查询变慢主要是因为索引没跟上或者逻辑跑偏了。

先说最重要的,减少子查询是关键。
去年我们跑那个电商项目,几百张表联查,光一个子查询就拖慢了1 0秒,用WITH语句合并后直接快了8 秒。
另外一点,CASE WHEN要慎用,尤其统计场景。
我们有个报表需求,用CASE WHEN嵌套三层,改成分组查询+COALESCE函数,跑时间从5 分钟缩到3 0秒。
还有个细节挺关键的,比如3 000量级数据,LIKE '%keyword'会全表扫描,换成IN('keyword1 ','keyword2 '),索引就能用上了。

我一开始也以为硬件是瓶颈,结果发现是JOIN顺序写反了。
后来发现不对劲,用EXPLAIN一查,居然在ON条件里做了字符串截取。
等等,还有个事,复合索引要按查询频率排序,比如我们项目把('user_id','order_date')索引调到('order_date','user_id'),效果立马提了一半。

最建议的做法是,先用EXPLAIN抓个慢查询,看WHERE子句和JOIN部分哪个 costing 最高,再针对性改。
不过别忘了,有时候数据库版本升级就能省事,比如PostgreSQL 1 2 的CTE性能比9 系强一倍。