検索
ホームページバックエンド開発PHPチュートリアルMYSQL の更新と最適化を忘れないでください。

はじめに

今日 (2015 年 8 月 5 日 5:34 PM) データベース内のテーブルの構造を調整し、いくつかのフィールドを追加して、以前のデータを更新しました。 更新の内容は次のとおりです。 既存のデータと一致する。フィールド url を追加し、新しく追加されたフィールド typetypeid を更新します。その後、データを更新するためにシェル スクリプトを作成しました。シェル スクリプトを実行した後、ジョイント インデックス uin_id が 1 つしかないのに、それを更新したときに混乱しました。次のアイデアがありました: url进行匹配,然后更新新加的字段typetypeid。后来就写了个shell脚本来刷数据,结果运行shell脚本后我就懵了,怎么这么慢~~~

情景再现

<code>CREATE TABLE `fuckSpeed` (
  `uin` bigint(20) unsigned NOT NULL DEFAULT 0,
  `id` int(11) unsigned NOT NULL DEFAULT 0,
  `url` varchar(255) NOT NULL DEFAULT '',
  `type` int(11) unsigned NOT NULL DEFAULT 0,
  `typeid` varchar(64) NOT NULL DEFAULT '',
  ......
  KEY `uin_id` (`uin`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;</code>

表结构大概是上面这样的(省略了好多字段),表中只有一个联合索引uin_id,而我在更新的时候是下面的思路:

  • 首先根据一个id范围获取到一定数量的数据
    select id,url from funkSpeed where id>=101 and id
  • 遍历所有的数据,对每一条数据进行更新
    #首先对数据进行处理,匹配获取type和typeid
    update fuckSpeed set type=[type],typeid=[typeid] where id=[id]
    按照上面的思路搞了之后,发现更新特别的慢,平均每秒钟3~5个左右,我也是醉了,我看看要更新的数据,总共有32w+条,这样更新下来大概需要24h+,也就是1天还要多,额~~哭了,想想肯定是哪里出问题了。

发现问题

首先我想到的是是不是因为只有一个进程在更新,导致很慢,我启动了5个进程,将id分段了,就像下面这样

<code>./update_url.sh 0 10000 &
./update_url.sh 10000 20001 &
./update_url.sh 20001 30001 &
./update_url.sh 30002 40002 &
./update_url.sh 40003 50003 &</code>

运行之后发现还是那样,速度没有提升多少,还是每秒钟更新3~5个左右,想想也是啊,时间不可能花费在插入数据之前的那些步骤(匹配、组装sql语句、。。。),应该是插入的时候有问题

再来看看我的sql语句select id,url from funkSpeed where id>=101 and id,这里,试着在命令行执行了下,结果如下

<code>mysql> select id,url from funkSpeed where id>=0 and id</code>

竟然花了0.18秒,这个时候我猜恍然大悟,联合索引我没有使用到,联合索引生效的条件是——必须要有左边的字段,用explain验证下,果然是这样:

<code>mysql> explain id,url from funkSpeed where id>=0 and id</code>

然后使用联合索引:

<code>mysql> select uin,id from funkSpeed where uin=10023 and id=162;
+------------+----------+
| uin        |   id     |
+------------+----------+
| 10023      | 162      |
+------------+----------+
1 row in set (0.00 sec)

mysql> explain select uin,id from funkSpeed where uin=10023 and id=162;
+-------------+------+---------------+----------+---------+-------------+------+-------------+
| table       | type | possible_keys | key      | key_len | ref         | rows | Extra       |
+-------------+------+---------------+----------+---------+-------------+------+-------------+
| funkSpeed   | ref  | uin_id        | uin_id   | 12      | const,const |    4 | Using index |
+-------------+------+---------------+----------+---------+-------------+------+-------------+
1 row in set (0.00 sec)</code>

可以看到几乎是秒查,这个时候基本可以断定问题是出现在索引这个地方了

我select的时候次数比较少,每两个select之间id相差10000,所以这里可以忽略掉,而且这里没办法优化,除非在id上面添加索引。

问题发生在update fuckSpeed set type=[type],typeid=[typeid] where id=[id],这里在更新的时候也是会用到查询的,我的mysql版本是5.5,不能explain update,不然肯定可以验证我所说的,这里要更新32w+条数据,每条数据都会去更新,每条数据0.2s左右,这太吓人了~~

解决问题

问题找到了,解决起来就容易多了~~

select的时候加了一个字段uin,改为下面这样select uin,id,url from funkSpeed where id>=101 and id,然后更新的时候使用<code>update fuckSpeed set type=[type],typeid=[typeid] where uin=[uin] id=[id]

  • まず、ID 範囲に基づいて一定量のデータを取得します

id>=101 および id
  • すべてのデータを走査し、各データを更新します #最初にデータを処理し、type と typeid を照合して取得します

    update funkSpeed set type=[type ], typeid=[typeid] where id=[id]

    上記の考えに従った後、更新されるデータは合計 320,000 件以上あり、平均して 1 秒あたり約 3 ~ 5 件であることがわかりました。 、更新には24時間以上かかります、つまり1日以上かかります、う〜〜、考えてみれば何か問題があるはずです。
  • 問題が見つかりました

    最初に考えたのは、更新が 1 つしかないため非常に遅くなるのではないかということで、5 つのプロセスを起動して ID をセグメント化しました。このように

    rrreee

    実行してみると、速度はあまり改善されておらず、依然として 1 秒あたり 3 ~ 5 回の更新が行われています。考えてみれば、挿入前の手順に時間を費やすことはできません。データ (SQL ステートメントの照合、アセンブルなど) を挿入するときに問題が発生するはずです

    私の SQL ステートメントを見てみましょう。select id,url from funkSpeed where id>=101 and id、ここでコマンドラインで実行してみます しばらくすると結果は以下の通り<p>rrreee</p>実際には0.18秒かかったのですが、この時ふと気づいたのでしょう。ジョイントインデックスが有効になる条件は、左側にフィールドがある必要があることです。 <p>ほぼ 2 回目の検索であることがわかります。この時点で、基本的にインデックスに問題が発生していると判断できます。<br><img src="/static/imghwm/default1.png" data-src="http://image.codes51.com/Article/image/20150805/20150805184938_2856.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="MYSQL の更新と最適化を忘れないでください。" > を選択すると、回数は比較的少なく、それぞれの 2 つの ID が選択されます。差は 10,000 であるため、ここでは無視できます。ID にインデックスを追加しない限り、最適化する方法はありません。 </p>
    この問題は、update funkSpeed set type=[type],typeid=[typeid] where id=[id] で発生します。私の mysql バージョンは 5.5 です。 更新を説明できません。そうでない場合は、ここで更新するデータが 320,000 以上あり、各データの更新には約 2 秒かかります。これは怖すぎます~~

    問題を解決してください

    問題が見つかったら、解決するのはずっと簡単になります~~🎜🎜 選択時にフィールド uin が追加され、次のように変更されましたselect uin,id,url from funkSpeed where id>=101 and id, then use <code>update funkSpeed set type=[type],typeid=[typeid] where uin =[uin] id=[id] となり、インデックスが使用されます。 🎜🎜 コードを 3 回、5 回、2 回変更した後、効果を確認するためにプロセスを開始しようとしましたが、結果は平均 30 回以上でした。 、すべて3時間程度で完了できるようになりました。 🎜🎜WeChat ID: love_skills🎜🎜🎜一生懸命働けば働くほど、あなたはもっと幸運になります!幸運であればあるほど、一生懸命働くことになります。 🎜🎜CEOになることも夢じゃない🎜🎜バイ・フメイに勝つことも夢ではない🎜🎜ディシの反撃も夢ではない🎜🎜今だ! !さあ🎜🎜🎜🎜 🎜 上記は、内容の側面も含めて MYSQL アップデートの最適化について紹介しました。PHP チュートリアルに興味のある友人に役立つことを願っています。 🎜 🎜 🎜
    声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
    PHP依存性噴射コンテナ:クイックスタートPHP依存性噴射コンテナ:クイックスタートMay 13, 2025 am 12:11 AM

    aphpDependencyInjectionContaineriSATOULTAINATINAGECLASSDEPTINCIES、強化測定性、テスト可能性、および維持可能性。

    PHPの依存噴射対サービスロケーターPHPの依存噴射対サービスロケーターMay 13, 2025 am 12:10 AM

    SELECT DEPENTENCINGINOFCENT(DI)大規模なアプリケーションの場合、ServicElocatorは小さなプロジェクトまたはプロトタイプに適しています。 1)DIは、コンストラクターインジェクションを通じてコードのテスト可能性とモジュール性を改善します。 2)ServiceLocatorは、センター登録を通じてサービスを取得します。これは便利ですが、コードカップリングの増加につながる可能性があります。

    PHPパフォーマンス最適化戦略。PHPパフォーマンス最適化戦略。May 13, 2025 am 12:06 AM

    phpapplicationscanbeoptimizedforspeedandEfficiencyby:1)enabingopcacheinphp.ini、2)PreparedStatementswithpordatabasequeriesを使用して、3)LoopswithArray_filterandarray_mapfordataprocessing、4)の構成ngincasaSearverseproxy、5)

    PHPメールの検証:電子メールが正しく送信されるようにしますPHPメールの検証:電子メールが正しく送信されるようにしますMay 13, 2025 am 12:06 AM

    PHPemailvalidationinvolvesthreesteps:1)Formatvalidationusingregularexpressionstochecktheemailformat;2)DNSvalidationtoensurethedomainhasavalidMXrecord;3)SMTPvalidation,themostthoroughmethod,whichchecksifthemailboxexistsbyconnectingtotheSMTPserver.Impl

    PHPアプリケーションをより速くする方法PHPアプリケーションをより速くする方法May 12, 2025 am 12:12 AM

    tomakephpapplicationsfaster、followthesesteps:1)useopcodecachinglikeopcacheTostoredscriptbytecode.2)最小化abasequeriesecachingingindexing.3)leveragephp7機能forbettercodeefficiency.4)

    PHP依存性インジェクション:コードのテスト可能性を改善しますPHP依存性インジェクション:コードのテスト可能性を改善しますMay 12, 2025 am 12:03 AM

    依存性注入(DI)は、明示的に推移的な依存関係によりPHPコードのテスト可能性を大幅に改善します。 1)DI分離クラスと特定の実装により、テストとメンテナンスが柔軟になります。 2)3つのタイプのうち、コンストラクターは、状態を一貫性に保つために明示的な式依存性を注入します。 3)DIコンテナを使用して複雑な依存関係を管理し、コードの品質と開発効率を向上させます。

    PHPパフォーマンスの最適化:データベースクエリの最適化PHPパフォーマンスの最適化:データベースクエリの最適化May 12, 2025 am 12:02 AM

    DatabaseQueryoptimizationInpholvesseveralstrategESTOEnhancePerformance.1)selectonlynlynlyndorycolumnStoredatedataTransfer.2)useindexingtospeedupdataretrieval.3)revenmecrycachingtostoreres sultsoffrequent queries.4)

    See all articles

    ホット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衣類リムーバー

    Video Face Swap

    Video Face Swap

    完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

    ホットツール

    EditPlus 中国語クラック版

    EditPlus 中国語クラック版

    サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

    ドリームウィーバー CS6

    ドリームウィーバー CS6

    ビジュアル Web 開発ツール

    AtomエディタMac版ダウンロード

    AtomエディタMac版ダウンロード

    最も人気のあるオープンソースエディター

    SublimeText3 中国語版

    SublimeText3 中国語版

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

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。