sql调优

  • 使用 WHERE 子句等过滤条件,减少返回结果集的数据量。
  • 尽可能在关联前进行数据过滤,减少关联操作。
  • 避免使用 SELECT *,只选择你需要的字段,减少数据传输量

eg 假设有一个订单管理系统,需要优化以下 SQL 查询:

SELECT * FROM orders 
JOIN customers ON orders.customer_id = customers.id 
WHERE orders.order_date > '2022-01-01'

加入订单表 orders 和客户表 customers 很可能都包含大量数据,我们可以首先尝试在WHERE 子句中加入更多的过滤条件,例如根据地区、订单状态等,以减少返回结果集的数据量。

eg 假设有两张表,一张是用户表(User),另一张是订单表(Order)。用户表中存储了用户的基本信息,订单表中存储了用户的订单信息,两张表通过用户ID进行关联。

当需要查询所有在过去一周内下过订单的活跃用户信息时,为了减少关联操作并提高性能,可以先从订单表中筛选出在过去一周内下过订单的用户ID,然后再根据这些用户ID去查询用户表中的用户信息

SELECT u.*
FROM User u
WHERE u.user_id IN (
    SELECT DISTINCT o.user_id
    FROM `Order` o
    WHERE o.order_date >= DATE_SUB(NOW(), INTERVAL 1 WEEK)
);

比对操作:避免了直接对两张表中的数据进行比对操作,因为通过子查询方式,我们可以先筛选出满足条件的数据再进行查询,避免了在关联阶段进行大量的比对操作。

  • 确保查询的字段上建立了索引,并保证索引的有效性。
  • 优化 SQL 查询语句中的关联条件,确保索引被充分利用。
SELECT * FROM orders 
JOIN customers ON orders.customer_id = customers.id 
WHERE orders.order_date > '2022-01-01'

确保 orders 表中的 order_date 字段和 customers 表中的 id 字段上都建立了索引,提高查询效率

  • 避免在关联条件中对字段进行函数处理

原因:索引失效: 当在关联条件中对字段进行函数处理时,数据库引擎通常无法有效使用索引。因为对字段进行函数处理后,原本的字段值发生了改变,使得无法直接匹配索引中的值,从而导致索引失效,数据库引擎可能无法有效地利用索引进行高效的数据查找。

假设我们有两个表 orders 和 customers,orders 表存储订单信息,customers 表存储客户信息,我们需要根据订单金额和客户等级进行关联查询。

首先,让我们看一下 orders 表的数据示例:

| order_id | amount |
|----------|--------|
| 1        | 100.5  |
| 2        | 200.8  |
| 3        | 300.3  |

customers 表的数据示例:

| customer_id | level |
|-------------|-------|
| 1           | 101   |
| 2           | 200   |
| 3           | 300   |

原始的 SQL 查询可能如下,其中对订单金额字段进行了舍入处理:

SELECT * 
FROM orders o
JOIN customers c ON ROUND(o.amount) = c.level;

为了避免在 JOIN 条件中进行函数处理,我们可以将数据处理提前到查询前。首先创建带有舍入后金额的临时表 tmp_orders:

CREATE TEMPORARY TABLE tmp_orders AS
SELECT order_id, ROUND(amount) AS rounded_amount
FROM orders;

然后基于处理后的数据进行关联查询:

SELECT *
FROM tmp_orders t
JOIN customers c ON t.rounded_amount = c.level;

通过这样的处理,我们在查询前即对订单金额进行了舍入处理并存储在临时表中,避免在关联条件中对字段进行函数处理,使得查询更加简洁和高效。

  • 将复杂计算的结果存储在临时表中:

原因:1、简化复杂逻辑: 复杂计算的结果存储在临时表中可以将复杂的逻辑简化为一个简单的数据访问操作,使得查询语句更加清晰和易于维护。
2、减少重复计算: 复杂计算通常会消耗较多的计算资源,将计算结果存储在临时表中可以避免重复进行这些复杂计算。在后续的查询中,直接访问临时表中的结果,无需重复进行耗时的计算,从而提高了查询的效率

假设我们有一个订单表 orders,需要从中筛选出订单金额大于一定阈值的订单,并计算订单金额超出阈值部分的差值。

首先,让我们看一下 orders 表的数据示例:

| order_id | amount |
|----------|--------|
| 1        | 900    |
| 2        | 1100   |
| 3        | 1200   |

原始的 SQL 查询可能如下,计算订单金额超出阈值部分的差值:

SELECT order_id, amount,
    CASE 
        WHEN amount > 1000 THEN amount - 1000
        ELSE 0
    END AS excess_amount
FROM orders
WHERE amount > 1000;

为了提高查询效率,我们可以将计算结果存储在临时表中,并后续查询该临时表。首先创建包含计算结果的临时表 tmp_excess_orders:

CREATE TEMPORARY TABLE tmp_excess_orders AS
SELECT order_id, amount,
    CASE 
        WHEN amount > 1000 THEN amount - 1000
        ELSE 0
    END AS excess_amount
FROM orders
WHERE amount > 1000;

然后可以直接查询这个临时表来获取结果:

SELECT *
FROM tmp_excess_orders;
  • 索引并不是越多越好,索引固然可以提高相应的select的效率,但同时也降低了insert 及 update 的效率

原因:索引建立越多,底层B树结构每个节点存储信息就越多,插入新数据可能需要重新平衡树结构,这可能涉及移动和重新排序节点,从而增加了操作的开销

  • 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。

原因:
1、查询性能提升:数字型字段比字符型字段在查询时通常具有更好的性能。数据库引擎可以更快地处理数字型数据的比较、排序和计算操作,相比之下,字符型数据需要更多的资源和时间来进行相同的操作。
2、提高连接性能:在数据库连接操作中,如果连接字段是数字型而不是字符型,连接操作的效率通常会更高。连接操作需要比较两个字段的值,并且通过索引来加速连接操作;对于数字型字段,比较和索引查找的效率通常比字符型字段更高。

可能导致全表扫描的几种情况:

  • 尽量避免使用in和not in,在where子句中使用in和not in,引擎将放弃使用索引而进行全表扫描。
  • 尽量避免使用!=或<>操作符,在 where语句中使用!=或<>,引擎将放弃使用索引而进行全表扫描。
  • 使用like的时候要注意是否会导致全表扫
慢sql查询怎么查
  1. 开启慢查询日志:

在 MySQL 数据库中,您可以通过编辑 MySQL 配置文件 my.cnf,找到并修改以下选项:

slow_query_log = 1
long_query_time = 1

slow_query_log 设为 1 以开启慢查询日志记录,long_query_time 指定慢查询的时间阈值,单位为秒。这里设置为 1 表示超过 1 秒的查询会被记录在慢查询日志中。

  1. 分析慢查询日志

定期检查慢查询日志文件,您可以使用以下命令找到慢查询日志文件路径:

SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'slow_query_log_file';

通过查看慢查询日志,您可以找到执行时间较长的 SQL 查询语句。

  1. 使用数据库性能分析工具

针对慢查询的 SQL 语句,您可以使用 MySQL 的 EXPLAIN 命令来查看查询执行计划,例如:

EXPLAIN SELECT * FROM your_table WHERE condition;

这将会显示查询执行计划以及可能的性能瓶颈,帮助您理解查询的执行方式和可能的优化路径。

  1. 优化 SQL 查询

根据分析结果,您可以针对性地对慢查询的 SQL 语句进行优化,例如添加索引、重构查询语句、优化数据库配置等。

面试题:
统计年龄在 19 到 24 岁之间年龄最大的人数

SELECT COUNT(*) AS max_age_count
FROM table_name
WHERE age >= 19 AND age <= 24
ORDER BY age DESC
LIMIT 1;
COUNT(*) ?

COUNT(*) 是 SQL 中用于统计符合特定条件的行数的聚合函数。它可以用来统计表中满足条件的记录的数量。

例如,如果您有一个名为 "students" 的表,其中包含了学生的信息,您可以使用 COUNT(*) 来统计表中的记录数量,如下所示:

SELECT COUNT(*) AS total_students
FROM students;

这将返回一个名为 "total_students" 的结果集,其中包含了表中记录的总数。

您也可以使用 COUNT(*) 结合 WHERE 子句来统计满足特定条件的记录数量,例如:

SELECT COUNT(*) AS passed_students
FROM students
WHERE score >= 60;

这将返回一个名为 "passed_students" 的结果集,其中包含了分数大于等于 60 分的学生的记录数量。

总之,COUNT(*) 是 SQL 中非常常用的聚合函数,用于统计行数,可以帮助您快速获取所需信息的数量统计。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,332评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,930评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,204评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,348评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,356评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,447评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,862评论 3 394
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,516评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,710评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,518评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,582评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,295评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,848评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,881评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,121评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,737评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,280评论 2 341

推荐阅读更多精彩内容