热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

大数据表的查询优化方案-mysql教程

如果有一张大表,表中的数据有几百万、几千万甚至上亿,要实现实时查询,查询的结果要在十秒钟之内出来,怎么办?如何做优化?本人现在做的项目中,有个表的数据超过1千万行,超过3G的数据。现在需要对表中的数据进行查询统计,之前由于没做优化,导致此表的

如果有一张大表,表中的数据有几百万、几千万甚至上亿,要实现实时查询,查询的结果要在十秒钟之内出来,怎么办?如何做优化? 本人现在做的项目中,有个表的数据超过1千万行,超过3G的数据。现在需要对表中的数据进行查询统计,之前由于没做优化,导致此表的

如果有一张大表,表中的数据有几百万、几千万甚至上亿,要实现实时查询,查询的结果要在十秒钟之内出来,怎么办?如何做优化?

本人现在做的项目中,有个表的数据超过1千万行,超过3G的数据。现在需要对表中的数据进行查询统计,之前由于没做优化,导致此表的查询效率非常低下,让使用者非常苦恼,于是本人参与了此表的优化。

举个类似的例子,比如表中的结构如下,现在要统计某一天出生的人口数,或者统计某一城市的人口数,或者某一城市某一天出生的人口数。

CREATE TABLE `population` (
  `population_id` bigint(64) NOT NULL AUTO_INCREMENT COMMENT '人口表',
  `name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT '姓名',
  `city` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '城市',
  `birthday` date DEFAULT NULL COMMENT '出生日期', 
  PRIMARY KEY (`population_id`)
)

查询某一城市某一天出生的人口数
SELECT COUNT(*) FROM population WHERE city='广州' AND birthday = '2014-11-02'
查询某一城市的人口数
SELECT COUNT(*) FROM population WHERE city='广州' 
查询某一天出生的人口数
SELECT COUNT(*) FROM population WHERE birthday = '2014-11-02'

提出了两个优化方案,

(1).优化索引

通过添加索引后,查询的效率得到极大的提升,常用查询的查询时间从原来的几十秒下降到几秒。

建立以下两个单列索引

ALTER TABLE `population`   
  ADD  INDEX `fk_city` (`city`),
  ADD  INDEX `fk_birthday` (`birthday`);

也可以建立以下两个组合索引

ALTER TABLE `population`   
  ADD  INDEX `fk_index1` (`city`, `birthday`),
  ADD  INDEX `fk_index2` (`birthday`, `city`);

(2).使用中间表
虽然索引优化可以将查询时间大大减少,但如果数据量达到一定量时,有些情况下索引到的数据达到几百万时,查询仍然会很慢,因此索引优化无法从根本上解决问题。现在表中的数据量越来越大,平均每个月要增加一两百万的数据,索引的优化方法只是暂时的,只能解决小数据量的查询问题,随着数据量的快速增长,索引带来的性能优化很容易达到极限,要寻找其他的解决方案。

我们根据业务需求的特点,创建中间表population_statistics,将表population中的统计数据存放到中间表population_statistics中,查询时直接从中间表population_statistics中查询。注意,在对表population进行增、删、改时,必须同时更新population_statistics中的数据,否则会出现数据不一致的错误!

CREATE TABLE `population_statistics` (
  `population_statistics_id` bigint(64) NOT NULL AUTO_INCREMENT COMMENT '人口统计表ID',
  `city` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT '城市',
  `birthday` int(32) DEFAULT NULL COMMENT '出生日期',
  `total_count` int(32) DEFAULT NULL COMMENT '人口数量',
  PRIMARY KEY (`population_statistics_id`),
  KEY `fk_city` (`city`),
  KEY `fk_birthday` (`birthday`)
)
查询某一城市某一天出生的人口数
SELECT total_count FROM population_statistics WHERE city='广州' AND birthday = '2014-11-02';
查询某一城市的人口数
SELECT COUNT(total_count) FROM population_statistics WHERE city='广州';
查询某一天出生的人口数
SELECT COUNT(total_count) FROM population_statistics WHERE birthday = '2014-11-02';

某个城市某一天的人口在表population中可能有几千甚至万的数据,而在统计表population_statistics中最多只有一条数据,也就是说统计表population_statistics中的数据量只有人口表population的几千分之一,再加上索引的优化,查询的速度会极大提高。

下面总结一下常用的大数据表优化方案.

1. 索引优化

通过建立合理高效的索引,提高查询的速度.

建议阅读本人写的一篇关于索引的博客

http://blog.csdn.net/brushli/article/details/39677387

2. SQL优化

组织优化SQL语句,使查询效率达到最优,在很多情况下要考虑索引的作用.

建议阅读考本人写的一篇关于索引的博客

http://blog.csdn.net/brushli/article/details/39677387

3. 水平拆表

如果表中的数据呈现出某一类特性,比如呈现时间特性,那么可以根据时间段将表拆分成多个。

比如按年划分、按季度划分、按月划分等等,查询时按时间段进行拆分查询,再把查询结果进行合并;

比如按地区将表拆分,不同地区的数据放在不同的表里面,然后对查询进行分拆,对查询结果进行合并。

4. 垂直拆表

将表按字段拆分成多个表,常用的字段放在一个表,不常用的字段或大字段放在另外一个表。由于数据库每次查询都是以块为单位,而每块的容量是有限的,通常是十几K或几十K,将表按字段拆分后,单次IO所能检索到的行数通常会提高很多,查询效率就能提高上去。

比如有成员表,结构如下:

CREATE TABLE `member` (
  `member_id` bigint(64) NOT NULL AUTO_INCREMENT COMMENT '成员表ID',
  `name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT '成员姓名',
  `age` int(32) DEFAULT NULL COMMENT '成员年龄',
  `introduction` text COLLATE utf8_bin COMMENT '成员介绍',
  PRIMARY KEY (`member_id`)
)

introduction是大字段,保存成员的介绍,这个大字段会严重影响查询效率,可以将它独立出来,单独形成一个表。

CREATE TABLE `member` (
  `member_id` bigint(64) NOT NULL AUTO_INCREMENT COMMENT '成员表ID',
  `name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT '成员姓名',
  `age` int(32) DEFAULT NULL COMMENT '成员年龄',
  PRIMARY KEY (`member_id`)
)

CREATE TABLE `member_introduction` (
  `member_introduction_id` bigint(64) NOT NULL AUTO_INCREMENT COMMENT '成员介绍表ID',
  `member_id` bigint(64) DEFAULT NULL COMMENT '成员ID',
  `introduction` text COLLATE utf8_bin COMMENT '成员介绍',
  PRIMARY KEY (`member_introduction_id`),
  KEY `fk_member_id` (`member_id`),
  CONSTRAINT `fk_member_id` FOREIGN KEY (`member_id`) REFERENCES `member` (`member_id`)
)

5. 建立中间表,以空间换时间

在有些情况下,是可以通过建立中间表来加快查询速度的,详情可看文章开头的例子。

6. 用内存缓存数据,以空间换时间

将常用而且不常修改的数据加载到内存中,直接从内存查询则可。

可以使用热门的缓存技术,如Memcache、Redis、Ehcache等。

7. 使用其他辅助技术

Solr:一种基于Lucene的JAVA搜索引擎技术


推荐阅读
  • 优化Flask应用的并发处理:解决Mysql连接过多问题
    本文探讨了在Flask应用中通过优化后端架构来应对高并发请求,特别是针对Mysql 'too many connections' 错误的解决方案。我们将介绍如何利用Redis缓存、Gunicorn多进程和Celery异步任务队列来提升系统的性能和稳定性。 ... [详细]
  • 本文介绍了一个基于 Java SpringMVC 和 SSM 框架的综合系统,涵盖了操作日志记录、文件管理、头像编辑、权限控制、以及多种技术集成如 Shiro、Redis 等,旨在提供一个高效且功能丰富的开发平台。 ... [详细]
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • 前言无论是对于刚入行工作还是已经工作几年的java开发者来说,面试求职始终是你需要直面的一件事情。首先梳理自己的知识体系,针对性准备,会有事半功倍的效果。我们往往会把重点放在技术上 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 本文将详细介绍如何在ThinkPHP6框架中实现多数据库的部署,包括读写分离的策略,以及如何通过负载均衡和MySQL同步技术优化数据库性能。 ... [详细]
  • 在安装 SQL Server 时,选择混合验证模式可以提供更高的灵活性和管理便利性。如果您已经安装了 SQL Server 并使用单一的 Windows 身份验证模式,可以通过以下步骤将其更改为混合验证模式。 ... [详细]
  • 本文探讨了如何通过一系列技术手段提升Spring Boot项目的并发处理能力,解决生产环境中因慢请求导致的系统性能下降问题。 ... [详细]
  • Spring Cloud学习指南:深入理解微服务架构
    本文介绍了微服务架构的基本概念及其在Spring Cloud中的实现。讨论了微服务架构的主要优势,如简化开发和维护、快速启动、灵活的技术栈选择以及按需扩展的能力。同时,也探讨了微服务架构面临的挑战,包括较高的运维要求、分布式系统的复杂性、接口调整的成本等问题。最后,文章提出了实施微服务时应遵循的设计原则。 ... [详细]
  • Redis 中的 Fork 机制与 Copy-On-Write 技术
    本文探讨了 Redis 在执行快照操作时如何利用 fork 创建子进程,并通过 Copy-On-Write 机制高效地管理内存资源。fork 调用的独特之处在于它仅被调用一次,却能在父进程和子进程中分别返回不同的值。 ... [详细]
  • win10个性化打不开如何解决
    本篇内容主要讲解“win10个性化打不开如何解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“win ... [详细]
  • 在 Redis 中,整数集合(IntSet)主要用于存储有序的整数集合。当集合中的所有元素均为整数且集合长度不超过512时,Redis 会自动使用 IntSet 来提高效率和节省内存。本文将详细介绍 IntSet 的结构及其工作原理。 ... [详细]
  • 本文探讨了大型服务端开发过程中常见的几个误区,包括异步任务处理不当、日志同步模式使用、网络操作未设置超时、缓存命中率及响应时间未统计、单一缓存模式、分布式缓存加锁不当以及团队管理上的误区,旨在帮助开发者避免这些常见错误。 ... [详细]
  • 字节跳动夏季招聘面试经验分享
    本文详细记录了字节跳动夏季招聘的面试经历,涵盖了一、二、三轮面试的技术问题及项目讨论,旨在为准备类似面试的求职者提供参考。 ... [详细]
  • 本文将指导您如何在Docker环境中高效地搜索、下载Redis镜像,并通过指定或不指定配置文件的方式启动Redis容器。同时,还将介绍如何使用redis-cli工具连接到您的Redis实例。 ... [详细]
author-avatar
燕子yanzi068_476
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有