ホームページ データベース mysql チュートリアル 在MySQL的InnoDB存储引擎中count(*)函数的优化

在MySQL的InnoDB存储引擎中count(*)函数的优化

Jun 07, 2016 pm 02:58 PM
innodb

在MySQL中,日常开发中比较常用的有MyISAM和InnoDB两种存储引擎。两者之间的其中一个区别是使用count(*)函数计算表的具体行数。

写这篇文章之前已经看过了很多数据库方面的优化内容,大部分都是加索引、使用事务、要什么select什么等等。然而,只是停留在阅读的层面上,很少有实践,因为没有遇到真实的项目,一切都是纸上谈兵。实践是检验真理的唯一标准,于是就想在数据库上测试一些性能优化的方案,比如索引之类的,但是不想使用假的数据,于是就想着能不能抓取网上的一些数据来作分析,后来自己通过PHP抓取了一些数据(这个博文即将补上),抓了大约110W的用户数据之后,当然需要统计一下具体的数量,于是我使用了以下的SQL语句(我使用的存储引擎是InnoDB):

SELECT COUNT(*) FROM tbl_name;

然而,发现需要运行14-20s的时间才能看到结果。

在MySQL的InnoDB存储引擎中count(*)函数的优化

这样的时间开销在真实的环境的用户体验是十分差的,试想一下,打开一个页面还要等接近20s才能看到数据,别说20s,就算是3s也是十分差的,于是便想在这方面做优化。

存储引擎

在MySQL中,日常开发中比较常用的有MyISAM和InnoDB两种存储引擎。两者之间的其中一个区别是使用count(*)函数计算表的具体行数。

因为MyISAM会保存表的具体行数,因此这段代码在MyISAM存储引擎中执行,MyISAM只要简单地读出保存好的行数即可。因此,如果表中没有使用事务之类的操作,这是最好的优化方案。然而,InnoDB存储引擎不会保存表的具体行数,因此,在InnoDB存储引擎中执行这段代码,InnoDB要扫描一遍整个表来计算有多少行。

查询优化命令--Explain

要弄懂查询性能在哪,首先,需要知道导致查询缓慢的瓶颈在哪。explain命令显示的rows是核心的性能指标,rows大,说明mysql需要扫描的行数就多,绝大部分rows大的语句执行一定很快。所以优化语句基本上都是在优化rows。

首先,看看上面的语句:

在MySQL的InnoDB存储引擎中count(*)函数的优化

可以看到,mysql扫描了整个表来执行本次查询。

奇怪的地方

在数据表的设计中,我是添加了唯一索引的,但是后来有一个语句是根据其中一个字段统计数量,当时添加了一个普通的索引,当我再执行了一遍上面的SQL语句,发现只需要0.2-0.3s的时间就能统计出表中的行数。

在MySQL的InnoDB存储引擎中count(*)函数的优化

不禁吓了一跳,误打误撞就发现了优化的方法:在InnoDB中,除了唯一索引之外,在其他字段添加一个普通索引(称为辅助索引)就能够提升count(*)函数的性能。但是这是为什么呢?explain一下:

在MySQL的InnoDB存储引擎中count(*)函数的优化

同样是扫描一样的行数,为什么添加一个普通索引就可以提高这么多的性能?于是便开始查找资料和阅读文档弄懂这个问题。

count(*)函数执行原理

正如在不同的存储引擎中,count(*)函数的执行是不同的。在MyISAM存储引擎中,count(*)函数是直接读取数据表保存的行记录数并返回,而在InnoDB存储引擎中,count(*)函数是先从内存中读取表中的数据到内存缓冲区,然后扫描全表获得行记录数的。在使用count函数中加上where条件时,在两个存储引擎中的效果是一样的,都会扫描全表计算某字段有值项的次数。

索引原理

因为是添加了索引之后才得到性能上的提升,于是便想到从索引的角度来探索。

根据官方文档上的定义:索引是帮助MySQL高效获取数据的数据结构。可以得知,索引的本质就是数据结构,添加索引的目的就是为了提高查询的效率。

使用索引的查询可以类比到字典,如果要查”mysql“这个单词,我们首先会定位到m字母,然后在m字母下面的单词中找y字母,以此类推,直到找到mysql这个单词,就能看到它在第几页,然后就去该页获取该单词更多的信息。想象一下,如果没有索引,那你就要在字典里一页一页的翻阅,效率十分低下。使用索引就是通过这样不断地缩小查询的范围来筛选出最终的结果。

那么在数据库也是一样的,但显然在数据库里使用索引要复杂许多。

磁盘存取与预读

一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。那么数据库在构建索引的时候就需要先从磁盘读取数据了,此时就要产生磁盘I/O消耗。而每次的数据读取,都要经历寻道时间、旋转延迟、传输时间三个部分。寻道时间是指磁臂移动到指定磁道所需要的时间,一般在5ms以内;旋转延迟就是磁盘转速;传输时间指的是将数据从磁盘读出并写入到内存的时间,这个时间较短,可以忽略不计。相对于内存存取,I/O存取的消耗要高几个数量级。因此,评价一个数据结构作为索引的优劣最重要的指标就是查找过程中磁盘I/O操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。

从上面的描述可以得知磁盘I/O是非常高昂的操作,根据操作系统的局部性原理:

当一个数据被用到时,其附近的数据也通常会马上被使用。

计算机操作系统在这方面做了一些优化,当一次I/O时,不光把当前磁盘地址的数据读取到内存缓冲区内,而且把相邻的数据也都读取到内存缓冲区内。这样一来,在读取数据时产生的I/O就少了很多了。因为在数据库中,每一次I/O读取的数据我们称之为一页(page),,一般为4k或8k,也就是说,我们读取一页内的数据时,实际上才发生了一次I/O。

根据以上的描述,我们可以初步得出结论,增加索引前后的性能差距体现在磁盘读取过程。但是在添加新的索引之前,我是添加了一个唯一索引的,后来发现在mysql中,我添加的唯一索引被称为聚簇索引,而后面添加的索引称为辅助索引,因此,让我们再来看看聚簇索引和辅助索引的区别。

聚簇索引(clustered index)和辅助索引(secondary index) 聚簇索引(clustered index)

每一个InnoDB存储引擎下的表都有一个特殊的索引用来保存每一行的数据,称为聚簇索引。通常情况下,聚簇索引是主键的同义词。在InnoDB中,mysql是这样选择聚簇索引的:

如果表中定义了PRIMARY KEY,那么InnoDB就会使用它作为聚簇索引;

否则,如果没有定义PRIMARY KEY,InnoDB会选择第一个有NOT NULL约束的唯一索引作为PRIMARY KEY,然后InnoDB会使用它作为聚簇索引;

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

mysql innodbとは何ですか mysql innodbとは何ですか Apr 14, 2023 am 10:19 AM

InnoDB は、MySQL のデータベース エンジンの 1 つです。現在、MySQL のデフォルトのストレージ エンジンであり、MySQL AB によるバイナリ リリースの標準の 1 つです。InnoDB は、二重トラック認証システムを採用しており、1 つは GPL 認証、もう 1 つは独自のソフトウェアです認可。 InnoDB は、トランザクション データベースに推奨されるエンジンであり、トランザクション セキュリティ テーブル (ACID) をサポートしています。InnoDB は、同時実行性を最大限にサポートできる行レベルのロックをサポートしています。行レベルのロックは、ストレージ エンジン層によって実装されます。

MySQL がバイナリ コンテンツから InnoDB 行フォーマットを認識する方法 MySQL がバイナリ コンテンツから InnoDB 行フォーマットを認識する方法 Jun 03, 2023 am 09:55 AM

InnoDB はディスク上のテーブルにデータを保存するストレージ エンジンであるため、シャットダウンして再起動した後でもデータは残ります。データ処理の実際のプロセスはメモリ内で発生するため、ディスク内のデータをメモリにロードする必要があります。書き込みまたは変更要求を処理している場合は、メモリ内の内容もディスクに更新する必要があります。また、ディスクへの読み取りおよび書き込みの速度は非常に遅いことがわかっており、これはメモリ内での読み取りおよび書き込みとは数桁異なります。したがって、テーブルから特定のレコードを取得したい場合、InnoDB ストレージ エンジンは読み取りを行う必要がありますか?ディスクからレコードを 1 つずつ取り出しますか? InnoDB で採用されている方法は、データを複数のページに分割し、ページをディスクとメモリ間の対話の基本単位として使用することです。InnoDB のページのサイズは通常 16 です。

mysql innodb例外を処理する方法 mysql innodb例外を処理する方法 Apr 17, 2023 pm 09:01 PM

1. mysql をロールバックして再インストールします。このデータを他の場所からインポートする手間を避けるために、まず現在のライブラリ (/var/lib/mysql/location) のデータベース ファイルのバックアップを作成します。次に、Perconaserver 5.7 パッケージをアンインストールし、元の 5.1.71 パッケージを再インストールし、mysql サービスを開始すると、Unknown/unsupportedtabletype:innodb というプロンプトが表示され、正常に開始できませんでした。 11050912:04:27InnoDB:バッファプールの初期化中、サイズ=384.0M11050912:04:27InnoDB:完了

MySQL の innoDB でのファントム読み取りを解決する方法 MySQL の innoDB でのファントム読み取りを解決する方法 May 27, 2023 pm 03:34 PM

1. MySQL トランザクション分離レベル これら 4 つの分離レベルでは、複数のトランザクションの同時実行性の競合がある場合、ダーティ リード、非反復読み取り、ファントム読み取りの問題が発生する可能性があり、innoDB は反復可能読み取り分離レベル モードでこれらの問題を解決します。ファントム リーディングの説明、2. ファントム リーディングとは? ファントム リーディングとは、図に示すように、同じトランザクション内で同じ範囲を前後 2 回クエリしたときに得られる結果が矛盾することを意味します。 . この時点では、条件を満たすデータは 1 つだけです。2 番目のトランザクションでは、データの行を挿入して送信します。最初のトランザクションが再度クエリを実行すると、取得される結果は、前のトランザクションの結果より 1 つ多くなります。最初のクエリ。データ。最初のトランザクションの最初と 2 番目のクエリは両方とも同じであることに注意してください

MySQL ストレージ エンジンの選択の比較: InnoDB、MyISAM、およびメモリのパフォーマンス インデックスの評価 MySQL ストレージ エンジンの選択の比較: InnoDB、MyISAM、およびメモリのパフォーマンス インデックスの評価 Jul 26, 2023 am 11:25 AM

MySQL ストレージ エンジンの選択の比較: InnoDB、MyISAM、およびメモリのパフォーマンス インデックスの評価 はじめに: MySQL データベースでは、ストレージ エンジンの選択がシステム パフォーマンスとデータの整合性において重要な役割を果たします。 MySQL はさまざまなストレージ エンジンを提供します。最も一般的に使用されるエンジンには、InnoDB、MyISAM、Memory などがあります。この記事では、これら 3 つのストレージ エンジンのパフォーマンス指標を評価し、コード例を通じて比較します。 1. InnoDB エンジン InnoDB は私のものです

INNODBフルテキスト検索機能を説明します。 INNODBフルテキスト検索機能を説明します。 Apr 02, 2025 pm 06:09 PM

INNODBのフルテキスト検索機能は非常に強力であり、データベースクエリの効率と大量のテキストデータを処理する能力を大幅に改善できます。 1)INNODBは、倒立インデックスを介してフルテキスト検索を実装し、基本的および高度な検索クエリをサポートします。 2)一致を使用してキーワードを使用して、ブールモードとフレーズ検索を検索、サポートします。 3)最適化方法には、単語セグメンテーションテクノロジーの使用、インデックスの定期的な再構築、およびパフォーマンスと精度を改善するためのキャッシュサイズの調整が含まれます。

MyISAM および InnoDB ストレージ エンジンを使用して MySQL のパフォーマンスを最適化する方法 MyISAM および InnoDB ストレージ エンジンを使用して MySQL のパフォーマンスを最適化する方法 May 11, 2023 pm 06:51 PM

MySQL は広く使用されているデータベース管理システムであり、ストレージ エンジンが異なればデータベースのパフォーマンスに与える影響も異なります。 MyISAM と InnoDB は、MySQL で最もよく使用される 2 つのストレージ エンジンですが、これらには異なる特性があり、不適切に使用するとデータベースのパフォーマンスに影響を与える可能性があります。この記事では、これら 2 つのストレージ エンジンを使用して MySQL のパフォーマンスを最適化する方法を紹介します。 1. MyISAM ストレージ エンジン MyISAM は、MySQL で最も一般的に使用されるストレージ エンジンであり、その利点は高速であり、ストレージ スペースが小さいことです。 MyISA

MySQL ストレージ エンジンの読み取りパフォーマンスを向上させるためのヒントと戦略: MyISAM と InnoDB の比較分析 MySQL ストレージ エンジンの読み取りパフォーマンスを向上させるためのヒントと戦略: MyISAM と InnoDB の比較分析 Jul 26, 2023 am 10:01 AM

MySQL ストレージ エンジンの読み取りパフォーマンスを向上させるためのヒントと戦略: MyISAM と InnoDB の比較分析 はじめに: MySQL は、最も一般的に使用されているオープン ソース リレーショナル データベース管理システムの 1 つで、主に大量の構造化データの保存と管理に使用されます。ほとんどのアプリケーションでは読み取り操作が主な操作であるため、アプリケーションではデータベースの読み取りパフォーマンスが非常に重要になることがよくあります。この記事では、MySQL ストレージ エンジンの読み取りパフォーマンスを向上させる方法に焦点を当て、一般的に使用される 2 つのストレージ エンジンである MyISAM と InnoDB の比較分析に焦点を当てます。

See all articles