优化SQL查询实现高效数据检索(一)

文章讲述了SQL查询优化的重要性,包括减少资源消耗、缩短执行时间和节省成本。提到了使用指定字段的SELECT代替SELECT*,避免使用SELECTDISTINCT并改用GROUPBY,以及避免使用循环,以提高查询效率。通过实例展示了优化前后查询的性能差异。
摘要由CSDN通过智能技术生成

大家好,SQL(结构化查询语言)可以帮助大家从数据库中收集数据,它是专为此而设计的,换句话说,它使用行和列来处理数据,让使用者能够使用SQL查询来操作数据库中的数据。

SQL查询

SQL查询是一系列指令,向数据库发出这些指令以从中收集信息;可以使用这些查询从数据库中收集和操作数据;通过使用它们可以创建报告,进行数据分析等;由于这些查询的形式和长度,执行时间可能会很长,特别是在处理大型数据表时。

SQL查询优化

SQL查询优化的目的是确保你有效地使用资源。通俗地说,它可以减少执行时间,节省成本并提高性能。这对于开发人员和数据分析师来说是一项重要的技能。不仅从数据库返回正确的数据很重要,了解如何有效地做到这一点也很重要。

应该始终问自己:“是否有更好的编写查询的方法?”

让我们更深入地探讨一下这些原因。

资源效率:未经过优化的SQL查询会消耗过多的系统资源,如CPU和内存。这可能会导致整体系统性能下降。优化SQL查询可以确保这些资源得到有效利用。这反过来会导致更好的性能和可扩展性。

减少执行时间:如果查询运行缓慢,这将对用户体验产生负面影响。或者如果有一个正在运行的应用程序,这会导致应用程序性能下降。优化查询可以帮助减少执行时间,提供更快的响应时间和更好的用户体验。

节省成本:优化查询可以减少支持数据库系统所需的硬件和基础设施。这可以在硬件、能源和维护成本方面节约成本。

SQL查询优化技术

这份流程图展示了在优化SQL查询时应遵循的建议步骤。我们将在示例中遵循相同的方法。值得注意的是,优化工具也可以帮助提高查询性能。因此,让我们从众所周知的SQL命令SELECT开始,探索这些技术。

  • 使用指定字段的SELECT

当使用SELECT *时,它将返回表中所有行和所有列,与其扫描整个数据库,不如在SELECT之后使用特定字段。

在示例中,我们将使用特定的列名替换SELECT *。正如大家看到的那样,这将减少检索的数据量。因此,查询运行得更快,因为数据库必须获取并提供请求的列,而不是整个表的所有列。这可以在表包含大量列或大量数据行时最大限度地减轻数据库的I/O负担。

以下是优化之前的代码:

SELECT * FROM customer;

以下是输出结果:

 总查询运行时间为260毫秒,对此进行改进,为了展示这一点,本文将只选择3个不同列而不是选择全部,你也可以根据项目需要选择所需的列。以下是代码:

SELECT customer_id, 
       age, 
       country 
FROM customer;

以下是输出结果:

 正如你所看到的,通过定义我们要选择的字段,我们不会强制数据库扫描其所有数据,因此运行时间从260毫秒减少到79毫秒。想象一下,如果有数百万或数十亿行,或者有数百列,则会有很大的区别。

  • 避免使用SELECT DISTINCT

SELECT DISTINCT用于返回指定列中的唯一值。为此,数据库引擎必须扫描整个表并删除重复的值。在许多情况下,使用类似GROUP BY的替代方法可以提高性能,因为可以减少处理的数据量。

以下是代码:

SELECT DISTINCT segment 
FROM customer;

以下是输出结果:

我们的代码检索了customer表中segment列的唯一值,数据库引擎必须处理表中的所有记录,识别重复值并仅返回唯一值。对于大型表格来说,这可能会耗费大量时间和资源。

在替代版本中,以下查询通过使用GROUP BY子句检索segment列中的唯一值。GROUP BY子句根据指定的列对记录进行分组,为每个组返回一条记录。

以下是代码:

SELECT segment
FROM customer
GROUP BY segment;

以下是输出结果:

在本例中,GROUP BY子句有效地根据segment列对记录进行分组,从而产生与SELECT DISTINCT查询相同的输出。

通过避免使用SELECT DISTINCT并改用GROUP BY,你可以优化SQL查询并将总查询时间从198毫秒减少到62毫秒,这是超过3倍的速度。

  • 避免使用循环

循环可能会导致你的查询速度变慢,因为它们强制数据库一条一条地遍历记录。如果可能的话,使用内置操作和SQL函数,这些函数可以利用数据库引擎的优化并更有效地处理数据。

让我们来定义一个带有循环的自定义函数:

CREATE OR REPLACE FUNCTION sum_ages_with_loop() RETURNS TABLE (country_name TEXT, sum_age INTEGER) AS $$
DECLARE
    country_record RECORD;
    age_sum INTEGER;
BEGIN
    FOR country_record IN SELECT DISTINCT country FROM customer WHERE segment = 'Corporate'
    LOOP
        SELECT SUM(age) INTO age_sum FROM customer WHERE country = country_record.country AND segment = 'Corporate';
        country_name := country_record.country;
        sum_age := age_sum;
        RETURN NEXT;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

上面的代码使用基于循环的方法来计算“Corporate”客户段中每个国家的年龄总和,它首先检索不同国家的列表,然后使用循环迭代每个国家,计算该国家客户的年龄总和。这种方法可能会很慢和低效,因为它是逐行处理数据。

现在让我们运行这个函数:

SELECT * 
FROM sum_ages_with_loop()

以下是输出结果:

使用此方法的运行时间为198毫秒,让我们看一下优化后的SQL代码:

SELECT country, 
       SUM(age) AS sum_age
FROM customer
WHERE segment = 'Corporate'
GROUP BY country;

以下是输出结果:
 

通常情况下,使用单个SQL查询的优化版本表现更佳,因为它利用了数据库引擎的优化能力。

为了在我们的第一个代码中获得相同的结果,我们使用了PL/pgSQL函数中的循环,这通常比使用单个SQL查询慢且不够有效,并且迫使编写更多的代码行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

python慕遥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值