表的字段多少对查询速度的影响

本文探讨了数据库表中字段数量对查询效率的影响,并通过实际案例对比了一个包含大量字段的表与拆分为多个字段较少的表之间的查询性能差异。文章提出在数据库设计时采用垂直分表的方法以提高查询速度。

表的字段多少对查询速度的影响

        一个表的字段太多很影响一些查询只需要查询某一个或者几个字段的查询效率,在某些数据库设计的时候,可以将某些很少查询的字段和经常查询的字段分离开来(个人理解为垂直分表),这样MySQL 查询时速度就会有很大提升;我个人觉得这可能是需要用到垂直分表的一些原因;

一、表结构

1、字段较多的表(数据大概30万条)

CREATE TABLE `tb_report_info` (
  `ID` char(16) NOT NULL,
  `HosipitalName` char(64) NOT NULL DEFAULT '',
  `MachNumber` char(16) NOT NULL DEFAULT '',
  `PatientNo` char(16) NOT NULL DEFAULT '',
  `Telephone` char(16) DEFAULT '',
  `PatientName` char(64) NOT NULL DEFAULT '',
  `Age` int(11) NOT NULL DEFAULT '0',
  `Gender` char(8) NOT NULL DEFAULT '',
  `Dept` char(16) NOT NULL DEFAULT '',
  `OutPatientNo` char(32) NOT NULL DEFAULT '',
  `InPatientNo` char(32) NOT NULL DEFAULT '',
  `Height` int(11) NOT NULL DEFAULT '0',
  `Weight` int(11) NOT NULL DEFAULT '0',
  `DetectType` char(16) NOT NULL DEFAULT '',
  `Proofer` char(16) NOT NULL DEFAULT '',
  `Auditor` char(16) NOT NULL DEFAULT '',
  `NetWorkPrice` char(16) NOT NULL DEFAULT '',
  `ExaminationNo` char(16) NOT NULL DEFAULT '',
  `ExaminationDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `Stiffness` float(8,2) NOT NULL DEFAULT '0.00',
  `Iqr` char(16) NOT NULL DEFAULT '',
  `IqrMed` char(16) DEFAULT '',
  `SuccessRate` char(8) NOT NULL DEFAULT '',
  `SubmitDoctor` char(16) NOT NULL DEFAULT '',
  `Diagnostician` char(16) NOT NULL DEFAULT '',
  `SecondOpinion` char(255) NOT NULL DEFAULT '',
  `Pressure` char(8) NOT NULL DEFAULT '',
  `Flai` float(8,2) NOT NULL DEFAULT '0.00',
  `FlaiIqr` char(8) NOT NULL DEFAULT '',
  `FlaiIqrMed` char(16) DEFAULT '',
  `Stiffness1` float(8,2) NOT NULL DEFAULT '0.00',
  `Flai1` float(8,2) NOT NULL DEFAULT '0.00',
  `Stiffness2` float(8,2) NOT NULL DEFAULT '0.00',
  `Flai2` float(8,2) NOT NULL DEFAULT '0.00',
  `Stiffness3` float(8,2) NOT NULL DEFAULT '0.00',
  `Flai3` float(8,2) NOT NULL DEFAULT '0.00',
  `Stiffness4` float(8,2) NOT NULL DEFAULT '0.00',
  `Flai4` float(8,2) NOT NULL DEFAULT '0.00',
  `Stiffness5` float(8,2) NOT NULL DEFAULT '0.00',
  `Flai5` float(8,2) NOT NULL DEFAULT '0.00',
  `Stiffness6` float(8,2) NOT NULL DEFAULT '0.00',
  `Flai6` float(8,2) NOT NULL DEFAULT '0.00',
  `Stiffness7` float(8,2) NOT NULL DEFAULT '0.00',
  `Flai7` float(8,2) NOT NULL DEFAULT '0.00',
  `Stiffness8` float(8,2) NOT NULL DEFAULT '0.00',
  `Flai8` float(8,2) NOT NULL DEFAULT '0.00',
  `Stiffness9` float(8,2) NOT NULL DEFAULT '0.00',
  `Flai9` float(8,2) NOT NULL DEFAULT '0.00',
  `Stiffness10` float(8,2) NOT NULL DEFAULT '0.00',
  `Flai10` float(8,2) NOT NULL DEFAULT '0.00',
  `FileName` char(64) NOT NULL DEFAULT '',
  `FilePath` char(128) NOT NULL DEFAULT '',
  `FileSize` char(8) NOT NULL DEFAULT '',
  `bAmodeImage` blob,
  `bAmodeImageLen` int(11) DEFAULT NULL,
  `bTmodeImage` blob,
  `bTmodeImageLen` int(11) DEFAULT NULL,
  `bEImage` blob,
  `bEImageLen` int(11) DEFAULT NULL,
  `IsParsed` enum('Y','N') NOT NULL DEFAULT 'N',
  `RecvDate` datetime DEFAULT NULL,
  `LastTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`ID`,`ExaminationDate`),
  KEY `index_exdate` (`ExaminationDate`),
  KEY `index_number` (`MachNumber`),
  KEY `UnionIndex` (`MachNumber`,`ExaminationNo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


2、字段较少的表(数据跟上表条数相同)

表1:

CREATE TABLE `tb_stiffness_info` (
  `Stiffness` float DEFAULT NULL,
  `MachNumber` char(16) DEFAULT NULL,
  `Age` int(11) DEFAULT NULL,
  `Height` int(11) DEFAULT NULL,
  `Weight` int(11) DEFAULT NULL,
  KEY `machkey` (`MachNumber`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

表二:

CREATE TABLE `tb_stiffness` (
  `Stiffness` float DEFAULT NULL,
  `MachNumber` char(16) DEFAULT NULL,
  KEY `machkey` (`MachNumber`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

二、速度测试

1、单表查询


2、单表分组查询


3、连接查询

综上说明,在我们设计数据库表的时候,我们需要充分考虑业务上的某些需求,将一些不常用的字段和常用的字段分离开来,这样能够让查询常用字段的时候速度得到一定的提升;


以上纯属个人观点,仅供参考!本人较菜,有错误请大家指正!非常感谢!

<think> 嗯,用户问的是在Doris中添加分桶字段是否能优化查询速度。这个问题其实涉及到Doris的核心存储机制,需要从分桶原理说起。 用户可能正在设计Doris结构,遇到了性能瓶颈。从ta引用的资料来看,应该已经了解过稀疏索引和物化视图等优化手段,现在想进一步通过分桶提升查询效率。不过用户可能混淆了"分桶字段"和"排序列"的概念——前者是物理存储的分区依据,后者是逻辑排序键。 让我拆解一下:Doris的分桶本质上是将数据划分为多个tablet(类似分片),每个tablet在物理上是独立存储的。当查询条件包含分桶字段时,系统可以快速定位到具体tablet,避免全扫描。这就像图书馆把书籍按编号分到不同书架,找书时直奔对应书架即可。 用户给的示例代码中DISTRIBUTED BY HASH(siteid) BUCKETS 10就是典型用法。这里siteid作为分桶字段,数据会按siteid的哈希值分散到10个桶中。查询where siteid=xxx时就能精准命中单个bucket,效果类似分库分库的路由机制。 不过要注意陷阱:分桶字段选择不当反而会劣化性能。比如选gender这种低基数字段,会导致数据倾斜——某些桶数据量过大。用户提到的"736亿*15亿关联查询"案例能成功,正是因为分桶字段选择合理。 突然想到用户引用[4]提到物化视图加布隆过滤器优化10倍速度的案例,其实可以和分桶配合使用:先通过分桶裁剪数据范围,再用布隆过滤器快速过滤,最后物化视图聚合结果,形成三级加速。 用户没有提及具体数据规模,但引用[3]提到十亿级关联查询,说明ta可能面临海量数据处理。这种情况下分桶字段最好选择高频过滤条件(如user_id)且基数适中(百万级)的字段,配合3-10个分桶效果最佳。要提醒ta通过EXPLAIN命令验证分桶裁剪是否生效。 对了,分桶数设置也有讲究:过少会导致并发度低,过多会增加元数据开销。通常建议每个tablet保持在1GB左右,根据总数据量推算分桶数。比如100GB数据分100个桶就比较合理。 </think> 在 Doris 中,**为添加分桶字段(`DISTRIBUTED BY` 子句)是优化查询速度的关键手段之一,通常能显著提升查询性能**。以下是详细解释: --- ### 分桶字段如何优化查询速度? 1. **数据分片并行计算** 分桶(`BUCKETS`)会将数据水平分割成多个分片(Tablet),每个 Tablet 独立存储且可被并行处理。查询时,Doris 能将任务分发到多个 Tablet 上同时执行,**充分利用集群的计算资源,加速扫描和聚合操作**[^1][^3]。 2. **精准数据定位** 当查询条件包含分桶字段时(如 `WHERE siteid = 123`),Doris 能直接定位到特定分桶,**避免全扫描**。例如: ```sql -- 创建时分桶字段为 siteid CREATE TABLE visit ( siteid INT, ... ) DISTRIBUTED BY HASH(siteid) BUCKETS 10; -- 查询命中分桶字段,直接过滤分片 SELECT * FROM visit WHERE siteid = 123; -- 仅扫描 siteid=123 所在的分桶 ``` 3. **优化关联查询(Join)** 若关联键(如 `user_id`)是分桶字段,Doris 可将大关联转化为 **本地分片间关联(Colocate Join)**,避免跨节点数据混洗(Shuffle),**显著降低网络开销**[^3]。例如: ```sql -- 两张按相同方式分桶(HASH(user_id) BUCKETS 10) SELECT * FROM table_a JOIN table_b ON table_a.user_id = table_b.user_id; -- Doris 自动触发 Colocate Join,性能提升明显 ``` 4. **均衡负载数据倾斜避免** 合理选择分桶字段(如高基数列)可确保数据均匀分布到各分片,**避免热点分片导致的性能瓶颈**。 --- ### 分桶字段的最佳实践 1. **选择高频过滤或关联的列** 优先将常用于 `WHERE` 条件或 `JOIN` 键的列作为分桶字段(例如用户 ID、日期等)。 2. **控制分桶数量** - 分桶数应集群节点数协调(建议为节点数的整数倍)。 - 单个分片数据量推荐 **1GB-10GB**(过大影响并行度,过小增加元数据开销)。 3. **结合排序键使用** 分桶排序键(`AGGREGATE KEY/UNIQUE KEY`)协同工作,可进一步加速范围查询[^1]: ```sql AGGREGATE KEY(siteid, city, username) -- 排序列 DISTRIBUTED BY HASH(siteid) BUCKETS 10; -- 分桶字段 ``` - 查询时按 `(siteid, city, username)` 顺序过滤,能最大化利用前缀索引。 --- ### 其他优化手段配合 - **物化视图**:对分桶后的数据创建物化视图(如预聚合),可进一步提升聚合查询速度[^2][^4]。 - **布隆过滤器**:在分桶基础上为高基数字段添加布隆过滤器,加速等值查询[^4]。 - **分区+分桶**:先按时间分区(`PARTITION BY`),再按业务键分桶,实现两级数据裁剪。 --- ### 结论 ✅ **添加分桶字段能有效优化 Doris 查询速度**,尤其适用于: - 包含分桶字段过滤条件的查询 - 大关联(Join) - 聚合(SUM/COUNT)类查询 > 通过分桶实现数据物理分片,结合并行计算、本地关联、前缀索引等机制,是 Doris 高性能的核心设计之一[^1][^3][^4]。 ---
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值