讲师中心 微信公众号
AI工具推荐 视频效率加速

为什么带有DISTINCT的SQL视图执行速度极慢?

阿墨小哥_1947

阿墨小哥_1947

发布时间:2026-08-31 10:39:44

|

730人浏览过

|

来源于php中文网

原创

DISTINCT慢的根本原因是全量去重而非索引缺失,需先拉取所有匹配行再排序或哈希去重;替代方案包括GROUP BY、EXISTS半连接、窗口函数,而非依赖索引或物化视图。

为什么带有distinct的sql视图执行速度极慢?

SELECT DISTINCT 会强制去重计算,不是加索引就能解决的

带 DISTINCT 的视图慢,根本原因不是“没走索引”,而是数据库必须把所有满足条件的行先拉出来,再做全量去重(通常走临时表 + 排序或哈希)。哪怕最终只返回10行,中间可能已扫描并暂存了百万行。这和 WHERE 或 JOIN 阶段能靠索引提前过滤有本质区别。

常见错误现象:EXPLAIN 显示 Using temporary; Using filesort,或者执行计划里出现 Materialize 步骤;实际耗时集中在“去重阶段”,而非“读数据阶段”。

  • 如果原表本身字段组合天然不重复(比如主键+固定关联字段),DISTINCT 就是冗余开销
  • DISTINCT 作用在多个字段上时,去重成本呈指数级上升(尤其含 TEXT/BLOB 类型)
  • 视图定义中嵌套了子查询或 JOIN 后再用 DISTINCT,会导致去重发生在宽表结果集上,放大中间数据量

视图里用 DISTINCT 时,索引基本无效

普通查询中,索引能加速 WHERE 过滤或 ORDER BY 排序;但 DISTINCT 的去重逻辑无法被 B-Tree 索引直接支持——索引不存储“是否重复”的元信息,数据库仍需取出所有候选行才能判断。

即使你为 DISTINCT 涉及的所有字段建了联合索引,MySQL/PostgreSQL 也仅可能用它避免回表或优化排序,但不会跳过去重步骤。SQL Server 的列存储索引例外,但普通 OLTP 场景极少使用。

  • 联合索引 idx_a_b_c 对 SELECT DISTINCT a, b FROM t 可能减少排序开销,但对 SELECT DISTINCT b, a 就无效(顺序不匹配)
  • 在视图定义中建索引毫无意义:视图本身不存数据,索引只能建在基表上
  • 试图用覆盖索引“骗过”去重(如 SELECT DISTINCT a FROM t WHERE b=1 加 idx_b_a)最多省掉回表,去重动作照旧

替代 DISTINCT 的三种实操路径

真正提速,得从源头消除重复产生的逻辑,而不是优化去重过程本身。

  • 用 GROUP BY 替代(当语义等价时):例如 SELECT DISTINCT user_id FROM orders → SELECT user_id FROM orders GROUP BY user_id。部分引擎对 GROUP BY 有更激进的优化(如 MySQL 8.0+ 的 Loose Index Scan)
  • 改写为半连接(EXISTS):比如查“下过单的城市”,不用 SELECT DISTINCT city FROM users u JOIN orders o ON u.id=o.user_id,而用 SELECT city FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id)
  • 业务层保证唯一性:如果视图输出本该唯一(如“每个用户最新订单时间”),就别用 DISTINCT,改用窗口函数 ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY create_time DESC) 过滤出 Top 1

视图定义中 DISTINCT 和物化视图的误区

有人以为把带 DISTINCT 的视图设为物化(如 PostgreSQL 的 MATERIALIZED VIEW)就能一劳永逸,其实风险更大:刷新时照样要全量重算去重逻辑,且锁表时间更长;若基表更新频繁,物化视图很快过期,反而引入一致性问题。

真正适合物化的,是聚合结果稳定、更新频率低的场景(如日级统计报表),而不是靠 DISTINCT “修”数据模型缺陷的视图。

最常被忽略的一点:DISTINCT 往往暴露了 JOIN 方式或数据建模的问题——比如一对多关系没控制好粒度,导致一条主记录被炸成多行。这时候该重构查询逻辑或补约束,而不是给视图贴去重膏药。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

3803

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

811

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

989

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

5621

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2583

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

5600

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

7361

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1010

2024.04.29

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

120

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn