SELECTを使用しないでください*

上の青いフォントをクリックして、「スター公式アカウント」を選択してください

高品質の記事、すぐに配達

舞台裏で公式アカウントをフォローして、支払いまたはモールに返信し、実際のプロジェクト情報とビデオ入手してください

著者:_チェンハハ

出典:blog.csdn.net/qq_39390545/article/details/106766965

インタビュアー:「
XiaoChen 、よく使用されるSQL最適化方法について教えてください。」Chen Xiaoha:「SELECT *を使用しないなど、クエリの効率が低いなど、多くの方法があります。バラバラ...」

インタビュアー:「SELECT *を使用しないのはなぜですか?どのような状況で非効率的ですか?」
Chen Xiaoha:「SELECT *には、列名を指定するよりも完全なテーブルクエリが1つ多いようです。また、いくつかの役に立たないフィールドもチェックしました。」

インタビュアー:「うーん...」
陳暁波:「えーと、もうだめ」

Chen Xiaoha:「... ??(いくつかの意味)」

インタビュアー:「ええと...他に何を聞きたいですか?」
陳暁波:「ハンマーをお願いし、履歴書をください!」

SQLで「SELECT *」を使わないことに関しては、仕事でも面接でも、誰もが耳を貸さないのが問題です。悪いですが、一般的な理解はまだ非常に浅く、多くの人がその底部。その原則を探ります。

この記事では、「SELECT *」の効率が低い理由とシナリオについて、あまり意味がありません。SQL関連のドライグッズの詳細については、WeChatパブリックアカウント「Javaバックエンド」に従って「666」と返信し、Javaテクノロジスタックのマニュアルをダウンロードしてください。

この記事はとても乾燥しています!自分のお茶を持参してください。読む時間がないので、最初にお茶を集めることを忘れないでください-長年テクニカルマネージャーに殴られてきたプログラマーからのアドバイス

目次

1.効率が低い理由

1.不要な列は、データ転送時間とネットワークオーバーヘッドを増加させます

2. varchar、blob、text、io操作などの役に立たない大きなフィールドの場合は追加されます

3.MySQLオプティマイザの「カバーインデックス」戦略の最適化の可能性を失った

第二に、インデックス知識の拡張

●ジョイントインデックス(a、b、c)

●ジョイントインデックスのメリット

1)オーバーヘッドを削減する

2)カバーインデックス

3)高効率

●インデックスはできるだけ多く作成されていますか?

三、経験


1.効率が低い理由

最新の「AliJava開発マニュアル(大山版)記事の最後に本のダウンロードリンクがあります」のMySQLの説明を見てみましょう。

4-1。[必須]テーブルクエリのクエリフィールドのリストとして*を使用しないでください。必須のフィールドを明確に指定する必要があります。

説明:

  • クエリアナライザの解析のコストを増やします。

  • 追加または削除されたフィールドは、resultMap構成と簡単に矛盾します。

  • 役に立たないフィールド、特にテキストタイプのフィールドはネットワークの消費を増やします。

開発マニュアルに記載されている理由はいくつかあります。詳しく見てみましょう。

1.不要な列は、データ転送時間とネットワークオーバーヘッドを増加させます

  1. 「SELECT *」データベースを使用すると、より多くのオブジェクト、フィールド、権限、属性、​​およびその他の関連コンテンツを解析する必要があります。複雑なSQLステートメントやよりハードな解析の場合、データベースに大きな負担がかかります。

  2. ネットワークオーバーヘッドの増加; *ログやIconMD5などの役に立たない大きなテキストフィールドが誤って表示されることがあり、データ転送サイズが幾何学的に増加します。DBとアプリケーションが同じマシン上にない場合、このオーバーヘッドは非常に明白です

  3. mysqlサーバーとクライアントが同じマシン上にあり、使用されるプロトコルがまだtcpである場合でも、通信には追加の時間が必要です。

2. varchar、blob、text、io操作などの役に立たない大きなフィールドの場合は追加されます

正確には、長さが728バイトを超えると、余分なデータが最初に別の場所にシリアル化されるため、このレコードを読み取るとio操作が追加されます。(MySQL InnoDB)

3.MySQLオプティマイザの「カバーインデックス」戦略の最適化の可能性を失った

SELECT *はインデックスをカバーする可能性を排除し、MySQLオプティマイザーに基づく「インデックスをカバーする」戦略は非常に高速で非常に効率的であり、業界で強く推奨されるクエリ最適化方法です。

たとえば、テーブルt(a、b、c、d、e、f)があります。ここで、aは主キーで、列bにはインデックスがあります。

次に、ディスク上に2つのB +ツリー、つまりクラスター化インデックスと補助インデックス(単一列インデックス、ジョイントインデックスを含む)があり、それぞれ(a、b、c、d、e、f)と(a、b)を保存します。クエリが列bのインデックスを介して一部のレコードを除外できる条件では、クエリは最初に補助インデックスを通過します。ユーザーが列aと列bのデータのみを必要とする場合、ユーザーがクエリするデータ補助インデックスから直接知ることができます。

ユーザーselect *が補助インデックスを使用して不要なデータを取得する場合は、最初に補助インデックスを使用してデータをフィルタリングし、次にクラスター化インデックスを使用してすべての列を取得します。これには、もう1つのb +ツリークエリが必要であり、速度は必然的にはるかに遅くなります。

写真はブログから取られたものです「私は行きます、なぜ左端の接頭辞の原則が失敗するのですか?」

補助インデックスのデータはクラスター化インデックスのデータよりもはるかに少ないため、多くの場合、補助インデックスを介したカバーインデックス(ユーザーが必要とするすべての列はインデックスを介して取得できます)はディスクを読み取る必要がありません。 、および内部から直接アクセスされ、クラスター化インデックスの可能性が非常に高くなります。データはディスク(外部メモリ)にあります(バッファプールのサイズとヒット率によって異なります)。この場合、1つはメモリの読み取りであり、もう1つはディスクの読み取りです。速度の違いは非常に大きく、ほぼ1桁の違いがあります。

第二に、インデックス知識の拡張

上記の補助インデックス、MySQLの補助インデックスには、単一列インデックス、ジョイントインデックス(複数列ジョイント)が含まれます。単一列インデックスについては詳しく説明しません。ここに、ジョイントインデックスの役割があります。

ジョイントインデックス(a、b、c)

共同インデックス(a、b、c)は、実際に3つのインデックス(a)、(a、b)、(a、b、c)を確立しました。

結合されたインデックスは、本の第1レベル、第2レベル、および第3レベルのディレクトリと考えることができます。たとえば、index(a、b、c)は、第1レベルのディレクトリbと同等です。は第1レベルのディレクトリの下の第2レベルのディレクトリであり、cは第2レベルのディレクトリの下の第3レベルのディレクトリです。ディレクトリを使用するには、最初にその親ディレクトリを使用する必要があります。ただし、第1レベルのディレクトリは除きます。

次のように:

ジョイントインデックスの利点

1)オーバーヘッドを削減する

ジョイントインデックス(a、b、c)を作成することは、実際には3つのインデックス(a)、(a、b)、(a、b、c)を作成することと同じです。インデックスを追加するたびに、書き込み操作のオーバーヘッドとディスクスペースのオーバーヘッドが増加します。大量のデータを含むテーブルの場合、ジョイントインデックスを使用すると、オーバーヘッドが大幅に削減されます。

2)カバーインデックス

ジョイントインデックス(a、b、c)の場合、次のSQLがある場合、

SELECT a,b,c from table where a='xx' and b = 'xx';

次に、MySQLは、テーブルに戻らずにインデックスをトラバースすることでデータを直接取得できます。これにより、ランダムなio操作の多くが削減されます。io操作、特にランダムioの削減は、実際にはDBAの主要な最適化戦略です。したがって、実際の実際のアプリケーションでは、インデックスをカバーすることは、パフォーマンスを向上させるための主要な最適化方法の1つです。

3)高効率

より多くのインデックス列がある場合、より少ないデータをジョイントインデックスでフィルタリングできます。たとえば、1000Wのデータを含むテーブルには次のSQLがあります。

select col1,col2,col3 from table where col1=1 and col2=2 and col3=3;

仮定:各条件でデータの10%を除外できると仮定します。

  • A.単一列のインデックスしかない場合は、1000W10%= 100wのデータをこのインデックスでフィルタリングしてから、テーブルに戻って、100wのピースからcol2 = 2およびcol3 = 3を満たすデータを見つけることができます。データの、次にソート、次にページング、など(再帰的);

  • B.(col1、col2、col3)ジョイントインデックスの場合、1000w 10%10%* 10%= 1wが3列のインデックスでフィルタリングされ、効率の向上が想像できます。

インデックスはできるだけ多く作成されていますか?

答えは当然ノーです

  • データ量が少ないテーブルにはインデックスを付ける必要がないため、追加のインデックスオーバーヘッドが増加します。

  • 頻繁に参照されない列には、一般的に使用されないため、インデックスを作成しないでください。インデックスが確立されていても、あまり意味がありません。

  • 頻繁に更新される列のインデックスは作成しないでください。挿入または更新の効率に確実に影響します。

  • データが繰り返されて均等に分散されているため、インデックス付けはあまり効果がありません(たとえば、性別フィールドは男性と女性のみで、インデックス付けには適していません)。

  • データの変更ではインデックスを維持する必要があります。つまり、インデックスが多いほど、維持するのに費用がかかります。

  • より多くのインデックスはより多くのストレージスペースを必要とします

三、経験

ここにあるこの古いアイアンは、MySQLに情熱を持っているか、マウスを転がすのが好きであることがわかると思います。来るのは運命です、もしあなたがこの文学から何かを持っているなら、あなたの手で賞賛にけちをつけないでください、そして売春婦を使うことを拒否してください〜

友人が私に尋ねました、あなたはSQL仕様をとても気にかけています、あなたは通常コードを書くときにSELECT *を使用しませんよね?

どうしてそれが可能でしょうか、毎日それを使ってください。これはコードでも使用されます(恥ずべきことです)。実際、私たちのプロジェクトは一般的に小さく、データ量を増やすことはできず、パフォーマンスはまだボトルネックに遭遇していないので、私はもっと甘やかされています。

この記事を書く主な理由は、この知識がインターネット上で要約されることはめったになく、標準化されていないためです。これは私自身とすべての人にとってより詳細な要約であり、覚えておく価値があります。インタビュアーとの会話を終えた後、彼はあなたのせいを見つけることができません。

ちなみに、みなさん、ありがとうございました。




有热门推荐????
Docker 入门终极指南,这是我见过最好的教程!再见,xShell,自己用Java撸一个Web版的,网友直呼:6662020 国内互联网公司的薪酬排名,加班时长排名 !IDEA这样 配置注释模板,让你高出一个逼格!!
Java后端线上问题排查常用命令收藏SpringBoot+Prometheus+Grafana实现应用监控和报警10个解放双手实用在线工具,有些代码真的不用手写!微信小程序练手实战:前端+后端(Java)
又一神操作,SpringBoot2.x 集成百度 uidgenerator搞定全局ID

点击阅读原文,前往学习SpringCloud实战项目

おすすめ

転載: blog.csdn.net/qq_17231297/article/details/115038157