当前位置: 首页 > news >正文

SQL最佳实践:避免使用COUNT=0

如果你遇到类似下面的 SQL 查询:

SELECT *
FROM customer c
WHERE 0 = (SELECT COUNT(*)FROM orders oWHERE o.customer_id = c.customer_id);

意味着有人没有遵循 SQL 最佳实践。该语句的作用是查找没有下过订单的客户,其中子查询使用了 COUNT 函数统计客户的订单数量,如果结果等于零,代表没有订单。

从逻辑上来讲,以上查询没有问题;但是它可能存在性能问题。原因在于 COUNT 函数需要统计订单数量,如果某个客户有大量订单,数据库需要计算出一个总数;即使客户的订单数量不多,仍然需要进行统计。

以下是 MySQL 中的执行计划:

EXPLAIN ANALYZE 
SELECT *
FROM customer c
WHERE 0 = (SELECT COUNT(*)FROM orders oWHERE o.customer_id = c.customer_id);-> Filter: (0 = (select #2))  (cost=111563.21 rows=1040858) (actual time=8.305..7043.840 rows=231117 loops=1)-> Table scan on c  (cost=111563.21 rows=1040858) (actual time=6.968..1104.438 rows=1048577 loops=1)-> Select #2 (subquery in condition; dependent)-> Aggregate: count(0)  (cost=1.30 rows=2) (actual time=0.005..0.005 rows=1 loops=1048577)-> Index lookup on o using customer_id (customer_id=c.customer_id)  (cost=1.15 rows=2) (actual time=0.004..0.005 rows=2 loops=1048577)

其中Aggregate表示子查询中执行了聚合操作,查询的执行时间大概是 7 秒。

实际上这个 COUNT 函数结果对于我们并不重要,我们只需要知道客户是否存在订单。这种情况下,最简单的方法就是使用 EXISTS 运算符:

SELECT *
FROM customer c
WHERE NOT EXISTS (SELECT 1FROM orders oWHERE o.customer_id = c.customer_id);

如果客户存在任何订单,子查询就会获得结果,NOT EXISTS 运算符就会排除对应的客户,从而避免统计全部订单数据。新的执行计划如下:

EXPLAIN ANALYZE 
SELECT *
FROM customer c
WHERE NOT EXISTS (SELECT 1FROM orders oWHERE o.customer_id = c.customer_id);-> Nested loop antijoin  (cost=217780392498.61 rows=2177801765412) (actual time=2273.676..3746.089 rows=231117 loops=1)-> Table scan on c  (cost=111871.61 rows=1040858) (actual time=2.191..804.896 rows=1048577 loops=1)-> Single-row index lookup on <subquery2> using <auto_distinct_key> (customer_id=c.customer_id)  (actual time=0.000..0.000 rows=1 loops=1048577)-> Materialize with deduplication  (cost=423621.04..423621.04 rows=2092314) (actual time=2797.545..2797.545 rows=1021689 loops=1)-> Filter: (o.customer_id is not null)  (cost=214389.64 rows=2092314) (actual time=0.811..1372.007 rows=2097157 loops=1)-> Index scan on o using customer_id  (cost=214389.64 rows=2092314) (actual time=0.809..1164.613 rows=2097157 loops=1)

新的查询计划使用了 antijoin 连接和物化(Materialize),执行时间不到 4 秒。

无论用户订单数量多还是少,NOT EXISTS 的性能都不会差于 COUNT 函数,而且绝大部分情况下它的性能会更好。

相关文章:

SQL最佳实践:避免使用COUNT=0

如果你遇到类似下面的 SQL 查询&#xff1a; SELECT * FROM customer c WHERE 0 (SELECT COUNT(*)FROM orders oWHERE o.customer_id c.customer_id);意味着有人没有遵循 SQL 最佳实践。该语句的作用是查找没有下过订单的客户&#xff0c;其中子查询使用了 COUNT 函数统计客…...

PG与ORACLE的差距

首先必须是XID 64&#xff0c;一个在极端环境下会FREEZE的数据库无论如何都无法承担关键业务系统的重任的&#xff0c;我们可以通过各种配置&#xff0c;提升硬件的性能&#xff0c;通过各种IT管控措施来尽可能避免在核心系统上面临FREEZE的风险&#xff0c;不过并不是每个企业…...

树莓派3B+驱动开发(2)- LED驱动(传统模式)

github主页&#xff1a;https://github.com/snqx-lqh 本项目github地址&#xff1a;https://github.com/snqx-lqh/RaspberryPiDriver 本项目硬件地址&#xff1a;https://oshwhub.com/from_zero/shu-mei-pai-kuo-zhan-ban 欢迎交流 笔记说明 如我在驱动开发总览中说的那样&…...

超详细搭建PhpStorm+PhpStudy开发环境

刚开始接触PHP开发&#xff0c;搭建开发环境是第一步&#xff0c;网上下载PhpStorm和PhpStudy软件&#xff0c;怎样安装和激活就不详细说了&#xff0c;我们重点来看一看怎样搭配这两个开发环境。 前提&#xff1a;现在假设你已经安装完PhpStorm和PhpStudy软件。 我的PhpStor…...

分析比对vuex和store模式

在 Vue 中&#xff0c;Vuex 和 store 模式 是两个不同的概念&#xff0c;它们紧密相关&#xff0c;主要用于管理应用的状态。下面我会详细介绍这两个概念&#xff0c;并通过例子帮助你更好地理解。 1. Vuex 是什么&#xff1f; Vuex 是 Vue.js 的一个状态管理库&#xff0c;用…...

C# 网络编程--基础核心内容

在现今软件开发中&#xff0c;网络编程是非常重要的一部分&#xff0c;本文简要介绍下网络编程的概念和实践。 C#网络编程的主要内容包括以下几个方面‌&#xff1a; : 上图引用大佬的图&#xff0c;大家也关注一下&#xff0c;有技术有品质&#xff0c;有国有家&#xff0c;情…...

【C++游戏程序】easyX图形库还原游戏《贪吃蛇大作战》(三)

承接上一篇文章&#xff1a;【C游戏程序】easyX图形库还原游戏《贪吃蛇大作战》&#xff08;二&#xff09;&#xff0c;我们这次来补充一些游戏细节&#xff0c;以及增加吃食物加长角色长度等设定玩法&#xff0c;也是本游戏的最后一篇文章。 一.玩家边界检测 首先是用来检测…...

uni-app H5端使用注意事项 【跨端开发系列】

&#x1f517; uniapp 跨端开发系列文章&#xff1a;&#x1f380;&#x1f380;&#x1f380; uni-app 组成和跨端原理 【跨端开发系列】 uni-app 各端差异注意事项 【跨端开发系列】uni-app 离线本地存储方案 【跨端开发系列】uni-app UI库、框架、组件选型指南 【跨端开…...

SpringBoot中的@Configuration注解

在Spring Boot中&#xff0c;Configuration注解扮演着非常重要的角色&#xff0c;它是Spring框架中用于定义配置类的一个核心注解。以下是Configuration注解的主要作用&#xff1a; 定义配置类&#xff1a; 使用Configuration注解的类表示这是一个配置类&#xff0c;Spring容器…...

十二、路由、生命周期函数

router路由 页面路由指的是在应用程序中实现不同页面之间的跳转,以及数据传递。通过 Router 模块就可以实现这个功能 2.1创建页面 之前是创建的文件,使用路由的时候需要创建页面,步骤略有不同 方法 1:直接右键新建Page(常用)方法 2:单独添加页面并配置2.1.1直接右键新建…...

【蓝桥杯每日一题】X 进制减法

X 进制减法 2024-12-6 蓝桥杯每日一题 X 进制减法 贪心 进制转换 题目大意 进制规定了数字在数位上逢几进一。 XX 进制是一种很神奇的进制, 因为其每一数位的进制并不固定&#xff01;例如说某 种 XX 进制数, 最低数位为二进制, 第二数位为十进制, 第三数位为八进制, 则 XX 进制…...

《蓝桥杯比赛规划》

大家好啊&#xff01;我是NiJiMingCheng 我的博客&#xff1a;NiJiMingCheng 这节课我们来分享蓝桥杯比赛规划&#xff0c;好的规划会给我们的学习带来良好的收益&#xff0c;废话少说接下来就让我们进入学习规划吧&#xff0c;加油哦&#xff01;&#xff01;&#xff01; 一、…...

C++算法练习day70——53.最大子序和

题目来源&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目思路分析 题目&#xff1a;寻找最大子数组和&#xff08;也称为最大子序和&#xff09;。 给定一个整数数组 nums&#xff0c;找到一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#x…...

import是如何“占领满屏“

import是如何“占领满屏“的&#xff1f; 《拒绝使用模块重导&#xff08;Re-export&#xff09;》 模块重导是一种通用的技术。在腾讯、字节、阿里等各大厂的组件库中都有大量使用。 如&#xff1a;字节的arco-design组件库中的组件&#xff1a;github.com/arco-design… …...

ceph /etc/ceph-csi-config/config.json: no such file or directory

环境 rook-ceph 部署的 ceph。 问题 kubectl describe pod dragonfly-redis-master-0Warning FailedMount 7m59s (x20 over 46m) kubelet MountVolume.MountDevice failed for volume "pvc-c63e159a-c940-4001-bf0d-e6141634cc55" : rpc error: cod…...

C语言——验证“哥德巴赫猜想”

问题描述&#xff1a; 验证"哥德巴赫猜想" 任何一个大于2的偶数都可以表示为两个质数之和。例如&#xff0c;4可以表示为22&#xff0c;6可以表示为33&#xff0c;8可以表示为35等 //验证"哥德巴赫猜想" //任何一个大于2的偶数都可以表示为两个质数之和…...

Flourish笔记:柱状图(Column chart (grouped))

文章目录 样式设定Chart Type&#xff1a;图表类型Controls & Filters&#xff1a;展示方式Colors&#xff1a;颜色bars&#xff1a;柱子的调整labels&#xff1a;柱子数字标注X axis&#xff1a;横坐标标签Y axis&#xff1a;纵坐标标签Plot BackgroundNumber FormatingLe…...

深度学习案例:DenseNet + SE-Net

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 回顾DenseNet算法 DenseNet&#xff08;Densely Connected Convolutional Networks&#xff09;是一种深度卷积神经网络架构&#xff0c;提出的核心思想是通过在每一层与前面所有层进行直接连接…...

excel文件合并,每个excel名称插入excel列

import pandas as pd import os # 设置文件夹路径 folder_path rC:\test # 替换为您的下载文件夹路径 output_file os.path.join(folder_path, BOM材料.xlsx) # 创建一个空的 DataFrame 用于存储合并的数据 combined_data pd.DataFrame() # 遍历文件夹中的所有文件 for …...

Linux 如何设置特殊权限?

简介 通过使用 setuid、setgid 、sticky&#xff0c;它们是 Linux 中的特殊权限&#xff0c;可以对文件和目录的访问和执行方式提供额外的控制。 命令八进制数字功能setuid4当执行文件时&#xff0c;它以文件所有者的权限运行&#xff0c;而不是执行它的用户的权限运行。setg…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...