搜尋
首頁資料庫mysql教程Mysql 性能优化教程_MySQL

bitsCN.com

认识数据索引为什么使用数据索引能提高效率

数据索引的存储是有序的

在有序的情况下,通过索引查询一个数据是无需遍历索引记录的

极端情况下,数据索引的查询效率为二分法查询效率,趋近于 log2(N)

如何理解数据索引的结构

数据索引通常默认采用btree索引,(内存表也使用了hash索引)。

单一有序排序序列是查找效率最高的(二分查找,或者说折半查找),使用树形索引的目的是为了达到快速的更新和增删操作。

在极端情况下(比如数据查询需求量非常大,而数据更新需求极少,实时性要求不高,数据规模有限),直接使用单一排序序列,折半查找速度最快。

实战范例 : ip地址反查

资源: Ip地址对应表,源数据格式为  startip, endip, area

源数据条数为 10万条左右,呈很大的分散性

目标:    需要通过任意ip查询该ip所属地区

性能要求达到每秒1000次以上的查询效率

挑战:    如使用 between … and 数据库操作,无法有效使用索引。

如果每次查询请求需要遍历10万条记录,根本不行。

方法:    一次性排序(只在数据准备中进行,数据可存储在内存序列)

              折半查找(每次请求以折半查找方式进行)

在进行索引分析和SQL优化时,可以将数据索引字段想象为单一有序序列,并以此作为分析的基础。

实战范例:复合索引查询优化实战,同城异性列表

资源: 用户表user,字段 sex性别;area 地区;lastlogin 最后登录时间;其他略

目标: 查找同一地区的异性,按照最后登录时间逆序

          高访问量社区的高频查询,如何优化。

              查询SQL: select * from user where area=’$area’ and sex=’$sex’ order by lastlogin desc limit 0,30;

挑战:    建立复合索引并不难, area+sex+lastlogin 三个字段的复合索引,如何理解?

              首先,忘掉btree,将索引字段理解为一个排序序列。

              如果只使用area会怎样?搜索会把符合area的结果全部找出来,然后在这里面遍历,选择命中sex的并排序。 遍历所有 area=’$area’数据!

              如果使用了area+sex,略好,仍然要遍历所有area=’$area’ and sex=’$sex’数据,然后在这个基础上排序!!

              Area+sex+lastlogin复合索引时(切记lastlogin在最后),该索引基于area+sex+lastlogin 三个字段合并的结果排序,该列表可以想象如下。

              广州女$时间1

              广州女$时间2

              广州女$时间3

              …

              广州男

….

              深圳女

….

数据库很容易命中到 area+sex的边界,并且基于下边界向上追溯30条记录,搞定!在索引中迅速命中所有结果,无需二次遍历!

如何理解影响结果集

影响结果集是数据查询优化的一个重要中间数据

查询条件与索引的关系决定影响结果集

如上例所示,即便查询用到了索引,但是如果查询和排序目标不能直接在索引中命中,其可能带来较多的影响结果。而这会直接影响到查询效率

微秒级优化

优化查询不能只看慢查询日志,常规来说,0.01秒以上的查询,都是不够优化的。

实战范例

和上案例类似,某游戏社区要显示用户动态,select * from userfeed where uid=$uid order by lastlogin desc limit 0,30;   初期默认以uid为索引字段, 查询为命中所有uid=$uid的结果按照lastlogin排序。 当用户行为非常频繁时,该SQL索引命中影响结果集有数百乃至数千条记录。查询效率超过0.01秒,并发较大时数据库压力较大。

解决方案:将索引改为 uid+lastlogin 复合索引,索引直接命中影响结果集30条,查询效率提高了10倍,平均在0.001秒,数据库压力骤降。

影响结果集的常见误区

影响结果集并不是说数据查询出来的结果数或操作影响的结果数,而是查询条件的索引所命中的结果数。

实战范例

某游戏数据库使用了innodb,innodb是行级锁,理论上很少存在锁表情况。出现了一个SQL语句(delete from tabname where xid=…),这个SQL非常用SQL,仅在特定情况下出现,每天出现频繁度不高(一天仅10次左右),数据表容量百万级,但是这个xid未建立索引,于是悲惨的事情发生了,当执行这条delete 的时候,真正删除的记录非常少,也许一到两条,也许一条都没有;但是!由于这个xid未建立索引,delete操作时遍历全表记录,全表被delete操作锁定,select操作全部被locked,由于百万条记录遍历时间较长,期间大量select被阻塞,数据库连接过多崩溃。

这种非高发请求,操作目标很少的SQL,因未使用索引,连带导致整个数据库的查询阻塞,需要极大提高警觉。

总结:

影响结果集是搜索条件索引命中的结果集,而非输出和操作的结果集。

影响结果集越趋近于实际输出或操作的目标结果集,索引效率越高。

请注意,我这里永远不会讲关于外键和join的优化,因为在我们的体系里,这是根本不允许的! 架构优化部分会解释为什么。

理解执行状态

常见分析手段

慢查询日志,关注重点如下

是否锁定,及锁定时间

如存在锁定,则该慢查询通常是因锁定因素导致,本身无需优化,需解决锁定问题。

影响结果集

如影响结果集较大,显然是索引项命中存在问题,需要认真对待。

Explain 操作

索引项使用

不建议用using index做强制索引,如未如预期使用索引,建议重新斟酌表结构和索引设置。

影响结果集

这里显示的数字不一定准确,结合之前提到对数据索引的理解来看,还记得嘛?就把索引当作有序序列来理解,反思SQL。

Set profiling , show profiles for query操作

执行开销

注意,有问题的SQL如果重复执行,可能在缓存里,这时要注意避免缓存影响。通过这里可以看到。

执行时间超过0.005秒的频繁操作SQL建议都分析一下。

深入理解数据库执行的过程和开销的分布

Show processlist

状态清单

Sleep 状态, 通常代表资源未释放,如果是通过连接池,sleep状态应该恒定在一定数量范围内

实战范例: 因前端数据输出时(特别是输出到用户终端)未及时关闭数据库连接,导致因网络连接速度产生大量sleep连接,在网速出现异常时,数据库 too many connections 挂死。

简单解读,数据查询和执行通常只需要不到0.01秒,而网络输出通常需要1秒左右甚至更长,原本数据连接在0.01秒即可释放,但是因为前端程序未执行close操作,直接输出结果,那么在结果未展现在用户桌面前,该数据库连接一直维持在sleep状态!

Waiting for net, reading from net, writing to net

偶尔出现无妨

如大量出现,迅速检查数据库到前端的网络连接状态和流量

案例: 因外挂程序,内网数据库大量读取,内网使用的百兆交换迅速爆满,导致大量连接阻塞在waiting for net,数据库连接过多崩溃

Locked状态

有更新操作锁定

通常使用innodb可以很好的减少locked状态的产生,但是切记,更新操作要正确使用索引,即便是低频次更新操作也不能疏忽。如上影响结果集范例所示。

在myisam的时代,locked是很多高并发应用的噩梦。所以mysql官方也开始倾向于推荐innodb。

Copy to tmp table

索引及现有结构无法涵盖查询条件,才会建立一个临时表来满足查询要求,产生巨大的恐怖的i/o压力。

很可怕的搜索语句会导致这样的情况,如果是数据分析,或者半夜的周期数据清理任务,偶尔出现,可以允许。频繁出现务必优化之。

Copy to tmp table 通常与连表查询有关,建议逐渐习惯不使用连表查询。

实战范例:

某社区数据库阻塞,求救,经查,其服务器存在多个数据库应用和网站,其中一个不常用的小网站数据库产生了一个恐怖的copy to tmp table 操作,导致整个硬盘i/o和cpu压力超载。Kill掉该操作一切恢复。

Sending data

Sending data 并不是发送数据,别被这个名字所欺骗,这是从物理磁盘获取数据的进程,如果你的影响结果集较多,那么就需要从不同的磁盘碎片去抽取数据,

偶尔出现该状态连接无碍。

回到上面影响结果集的问题,一般而言,如果sending data连接过多,通常是某查询的影响结果集过大,也就是查询的索引项不够优化。

如果出现大量相似的SQL语句出现在show proesslist列表中,并且都处于sending data状态,优化查询索引,记住用影响结果集的思路去思考。

Freeing items

理论上这玩意不会出现很多。偶尔出现无碍

如果大量出现,内存,硬盘可能已经出现问题。比如硬盘满或损坏。

Sorting for …

和Sending data类似,结果集过大,排序条件没有索引化,需要在内存里排序,甚至需要创建临时结构排序。

其他

还有很多状态,遇到了,去查查资料。基本上我们遇到其他状态的阻塞较少,所以不关心。

分析流程

基本流程

详细了解问题状况

Too many connections 是常见表象,有很多种原因。

索引损坏的情况在innodb情况下很少出现。

如出现其他情况应追溯日志和错误信息。

了解基本负载状况和运营状况

基本运营状况

当前每秒读请求

当前每秒写请求

当前在线用户

当前数据容量

基本负载情况

学会使用这些指令

Top

Vmstat

uptime

iostat

df

Cpu负载构成

特别关注i/o压力( wa%)

多核负载分配

内存占用

Swap分区是否被侵占

如Swap分区被侵占,物理内存是否较多空闲

磁盘状态

硬盘满和inode节点满的情况要迅速定位和迅速处理

bitsCN.com

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何查证JBL耳机的真假信息如何查证JBL耳机的真假信息Dec 29, 2023 pm 10:54 PM

jbl耳机是很多听音乐用户的首选,好评如潮,但是对于假货大家还是非常的害怕的,那么jbl耳机怎么查询真伪来避免这个问题呢?下面就看看怎么查询吧。jbl耳机怎么查询真伪:1、首先进入“中国商品信息验证中心”。2、然后输入查询码,即可查看是否正确从而判断是不是真货。3、也可以去通过耳机声音的清晰度来进行分辨。正牌的耳机声音是非常的清晰的,音质也不会出现改变。假牌的耳机声音会有很多的掺杂,音质也是特别的差。4、大家可以将自己的耳机声音开到最大,看看是不是很和谐,真耳机声音都是一样的。但是假耳机的声音开

买过比特币怎么查询,怎么看自己买没买过比特币买过比特币怎么查询,怎么看自己买没买过比特币Feb 04, 2024 am 08:09 AM

现在怎么买比特币的800字公众号文章随着比特币的价格飙升,越来越多的人开始关注比特币,也有越来越多的人想要投资比特币。但是,投资比特币也是有风险的,所以在投资之前,需要了解相关知识,并做好风险控制。那么现在怎么买比特币呢?首先,为了投资比特币,您需要准备一个比特币钱包。比特币钱包是一种软件,用于存储、发送和接收比特币资金。根据您的需求,有多种类型的比特币钱包可供选择,例如硬件钱包、软件钱包和网络钱包。每种钱包都有其独特的特点,您可以根据自己的需求选择适合自己的。其次,你需要选择一个可靠的比特币交

steam怎么查询账号idsteam怎么查询账号idFeb 07, 2024 pm 12:09 PM

Steam是一个整合游戏下载平台,玩家可以在该平台上购买正版的游戏,也可以跟其他玩家进行沟通讨论交流。有小伙伴知道steam怎么查询账号id吗,下面小编就给大家详细介绍一下steam查询账号id的方法,有需要的小伙伴可以来看一看。查询方法:1、双击打开软件,点击上方菜单栏中的"查看"。2、然后点击下方选项列表中的"设置"。3、在打开的窗口界面中,点击左侧栏中的"账户"选项,然后找到右侧中的"账户名称"即可查询到账号id。

PHP如何查询Oracle数据库中的数据PHP如何查询Oracle数据库中的数据Jul 13, 2023 pm 07:34 PM

PHP如何查询Oracle数据库中的数据随着互联网时代的到来,网站和应用程序的开发越来越普遍。而数据库作为数据存储和管理的关键技术,也成为了开发者们必备的工具之一。其中,Oracle数据库作为一款功能强大、稳定可靠的关系型数据库管理系统,在企业级应用中得到了广泛应用。而在开发网站或应用程序时,如何使用PHP进行Oracle数据库的查询是一个非常重要的问题。在

PHP表单处理:表单数据查询与筛选PHP表单处理:表单数据查询与筛选Aug 07, 2023 pm 06:17 PM

PHP表单处理:表单数据查询与筛选引言在Web开发中,表单是一种重要的交互方式,用户可以通过表单向服务器提交数据并进行进一步的处理。本文将介绍如何使用PHP处理表单数据的查询与筛选功能。表单的设计与提交首先,我们需要设计一个包含查询与筛选功能的表单。常见的表单元素包括输入框、下拉列表、单选框、复选框等,根据具体需求进行设计。用户在提交表单时,会将数据以POS

查询从节点X开始,距离最多为D的子树中的最小权重查询从节点X开始,距离最多为D的子树中的最小权重Aug 25, 2023 am 11:25 AM

在进行计算机编程时,有时需要求出源自特定节点的子树的最小权重,条件是该子树不能包含距离指定节点超过D个单位的节点。这个问题出现在各个领域和应用中,包括图论、基于树的算法和网络优化。子树是较大树结构的子集,指定的节点作为子树的根节点。子树包含根节点的所有后代及其连接边。节点的权重是指分配给该节点的特定值,可以表示其重要性、重要性或其他相关指标。在这个问题中,目标是找到子树中所有节点中的最小权重,同时将子树限制在距离根节点最多D个单位的节点。在下面的文章中,我们将深入研究从子树中挖掘最小权重的复杂性

MySQL中如何进行数据的时序存储和查询?MySQL中如何进行数据的时序存储和查询?Jul 30, 2023 pm 03:09 PM

MySQL中如何进行数据的时序存储和查询?在许多应用场景中,对于数据的时序性要求是非常常见的,比如传感器数据的监测、日志记录等。MySQL作为一种常用的关系型数据库,也提供了一些方法来进行时序数据的存储和查询。一种常见的方法是使用时间戳字段来存储数据的时间信息。在MySQL中,可以使用TIMESTAMP或DATETIME类型的字段来存储时间。TIMESTAM

高德地图API文档解读:Java代码实现公交车在线运行状态查询高德地图API文档解读:Java代码实现公交车在线运行状态查询Jul 29, 2023 pm 10:45 PM

高德地图API文档解读:Java代码实现公交车在线运行状态查询导语:随着城市的发展,公共交通的重要性越来越凸显出来。人们对公交车的运行状态有着强烈的需求,例如实时到站时间、拥挤程度等信息。高德地图提供了强大的API以满足这方面的需求。本文将解读高德地图API文档,使用Java代码实现公交车在线运行状态查询,并提供代码示例。API概述高德地图API提供了丰富的

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

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

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!