首頁 資料庫 mysql教程 大数据表的查询优化方案

大数据表的查询优化方案

Jun 07, 2016 pm 04:06 PM
最佳化 數據表 方案 查詢

如果有一张大表,表中的数据有几百万、几千万甚至上亿,要实现实时查询,查询的结果要在十秒钟之内出来,怎么办?如何做优化? 本人现在做的项目中,有个表的数据超过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搜索引擎技术

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

12306怎麼查詢歷史購票紀錄 查看歷史購票紀錄的方法 12306怎麼查詢歷史購票紀錄 查看歷史購票紀錄的方法 Mar 28, 2024 pm 03:11 PM

12306訂票app下載最新版是一款大家非常滿意的出行購票軟體,想去哪裡就去那裡非常方便,軟體內提供的票源非常多,只需要通過實名認證就能在線購票,所有用戶的出行車票機票都可以輕鬆買到,享受不同的優惠折扣。還能提前開啟預約搶票,預約飯店、專車接送都是可以的,有了它想去哪裡就去那裡一鍵購票,出行更加簡單方便,讓大家的出行體驗更舒服,現在小編在線詳細為12306用戶帶來查看歷史購票記錄的方法。  1.打開鐵路12306,點擊右下角我的,點擊我的訂單  2.在訂單頁面點擊已支付。  3.在已支付頁

學信網如何查詢自己的學歷 學信網如何查詢自己的學歷 Mar 28, 2024 pm 04:31 PM

學信網如何查詢自己的學歷?在學信網中是可以查詢到自己的學歷,很多用戶都不知道如何在學信網中查詢到自己的學歷,接下來就是小編為用戶帶來的學信網查詢自己學歷方法圖文教程,感興趣的用戶快來一起看看吧!學信網使用教程學信網如何查詢自己的學歷一、學信網入口:https://www.chsi.com.cn/二、網站查詢:第一步:點選上方學信網位址,進入首頁點選【學歷查詢】;第二步:在最新的網頁中點選如下圖箭頭所示的【查詢】;第三步:之後在新頁面點選【的登陸學信檔案】;第四步:在登陸頁面輸入資料點選【登陸】;

C++ 程式最佳化:時間複雜度降低技巧 C++ 程式最佳化:時間複雜度降低技巧 Jun 01, 2024 am 11:19 AM

時間複雜度衡量演算法執行時間與輸入規模的關係。降低C++程式時間複雜度的技巧包括:選擇合適的容器(如vector、list)以最佳化資料儲存和管理。利用高效演算法(如快速排序)以減少計算時間。消除多重運算以減少重複計算。利用條件分支以避免不必要的計算。透過使用更快的演算法(如二分搜尋)來優化線性搜尋。

MySQL與PL/SQL的異同比較 MySQL與PL/SQL的異同比較 Mar 16, 2024 am 11:15 AM

MySQL與PL/SQL是兩種不同的資料庫管理系統,分別代表了關係型資料庫和過程化語言的特性。本文將比較MySQL和PL/SQL的異同點,並附帶具體的程式碼範例進行說明。 MySQL是一種流行的關聯式資料庫管理系統,採用結構化查詢語言(SQL)來管理和操作資料庫。而PL/SQL是Oracle資料庫特有的過程化語言,用於編寫預存程序、觸發器和函數等資料庫物件。相同

優化WIN7系統開機啟動項目的操作方法 優化WIN7系統開機啟動項目的操作方法 Mar 26, 2024 pm 06:20 PM

1.在桌面上按組合鍵(win鍵+R)開啟運行窗口,接著輸入【regedit】,回車確認。 2.開啟登錄編輯程式後,我們依序點選展開【HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorer】,然後看目錄裡有沒有Seri​​alize項,如果沒有我們可以點選右鍵Explorer,新建項,並將其命名為Serialize。 3.接著點選Serialize,然後在右邊窗格空白處點選滑鼠右鍵,新建一個DWORD(32)位元值,並將其命名為Star

解決 PHP 函數效率低的方法有哪些? 解決 PHP 函數效率低的方法有哪些? May 02, 2024 pm 01:48 PM

PHP函數效率最佳化的五大方法:避免不必要的變數複製。使用引用以避免變數複製。避免重複函數呼叫。內聯簡單的函數。使用數組優化循環。

Vivox100s參數配置大揭密:處理器效能如何最佳化? Vivox100s參數配置大揭密:處理器效能如何最佳化? Mar 24, 2024 am 10:27 AM

Vivox100s參數配置大揭密:處理器效能如何最佳化?在當今科技快速發展的時代,智慧型手機已經成為我們日常生活不可或缺的一部分。作為智慧型手機的重要組成部分,處理器的效能優化直接關係到手機的使用體驗。 Vivox100s作為一款備受矚目的智慧型手機,其參數配置備受關注,尤其是處理器效能的最佳化議題更是備受用戶關注。處理器作為手機的“大腦”,直接影響手機的運行速度

基於哈希表的資料結構優化PHP數組交集和並集的計算 基於哈希表的資料結構優化PHP數組交集和並集的計算 May 02, 2024 pm 12:06 PM

利用雜湊表可最佳化PHP數組交集和並集計算,將時間複雜度從O(n*m)降低到O(n+m),具體步驟如下:使用雜湊表將第一個數組的元素映射到布林值,以快速找出第二個陣列中元素是否存在,提高交集計算效率。使用雜湊表將第一個陣列的元素標記為存在,然後逐一新增第二個陣列的元素,忽略已存在的元素,提高並集計算效率。

See all articles