MySQL の複数テーブル関連のクエリと複数の単一テーブルのクエリではどちらが効率的ですか?
データ量が十分に大きくない場合、結合を使用しても問題はありませんが、通常はサービス層で実行されます。リソースは非常に高価であり、データベースにはサービスが必要です 書き込みと読み取りの両方に CPU 消費が必要です データベースのスループットを向上させるために、ビジネスは数百マイクロ秒からミリ秒の遅延ギャップを気にせず、より多くのリソースを投入します結局のところ、コンピューティングリソースは水平方向に拡張するのが簡単ですが、データベースは難しいため、ほとんどの企業は純粋なコンピューティング操作をサービス層に置き、データベースをトランザクション機能を備えたKVシステムとして使用することになります。ビジネス中心の軽量システム DB アーキテクチャのアイデア
2 番目: 多くの複雑なビジネスでは、歴史的な開発上の理由により、1 つのデータベースだけを使用することはできません。一般に、ミドルウェアの層が複数のデータベースに追加されます。データベース間を結合する方法はなく、当然のことながら、ビジネスはデータベースとの結合を減らすためにサービス層を抽象化します。
3 番目: 一部の大企業では、データの規模が大きいため、データベースを別々のデータベースとテーブルに分割する必要があります。別々のデータベースとテーブルを適用する場合、結合の使用も対象となります。シャーディング キーにより、結合される 2 つのテーブルが同じ物理データベース内にあることが明確になります。一般に、ミドルウェアはクロスデータベース結合を十分にサポートしていません。
非常に一般的なビジネス例を挙げると、サブデータベースとサブテーブルでは、2 つのテーブルを同期して更新する必要があります。2 つのテーブルは異なる物理ライブラリにあります。データの一貫性を確保するには、1 つのテーブルを同期して更新する必要があります。方法は、分散トランザクション ミドルウェアを使用することです。分散トランザクション ミドルウェアでは、2 つの更新操作が 1 つのトランザクションに組み込まれますが、このような操作には通常、グローバル ロックが必要であり、パフォーマンスが非常に遅くなります。ただし、企業によっては、短期間のデータの不整合を許容できる場合もあります。これを行うにはどうすればよいですか?これらを個別に更新しますが、データの書き込みに失敗するという問題が発生します。その後、スケジュールされたタスクを開始し、A テーブルで失敗した行をスキャンし、B テーブルも正常に書き込まれているかどうかを確認してから、2 つの関連付けをペアにします。現時点では結合を使用してレコード修正を行うことはできません。データはサービス層に取得され、アプリケーション自体によってマージされることのみ可能です。 。 。
実際、関連するクエリを分解してクエリを再構築すると、次のような利点があります。キャッシュをより効率的にします。
多くのアプリケーションは、単一テーブルのクエリに対応する結果オブジェクトを簡単にキャッシュできます。また、MySQL のクエリ キャッシュは、関連付け内のテーブルが変更されるとクエリ キャッシュが使用できなくなりますが、分割後、テーブルがほとんど変更されない場合は、そのテーブルに基づいたクエリを繰り返すことができるため、クエリ キャッシュの結果を使用します。
クエリを分割した後、単一のクエリを実行すると、ロックの競合を軽減できます。
アプリケーション層で関連付けを行うと、データベースの分割が容易になり、高いパフォーマンスとスケーラビリティを実現できます。
クエリ自体の効率も向上する可能性があります。
クエリにより、冗長なレコードを削減できます。
さらに、これは、MySQL のネストされたリング関連付けを使用する代わりに、アプリケーションにハッシュ関連付けを実装することと同等であり、シナリオによっては、ハッシュ関連付けの方がはるかに効率的です。
クエリ ステートメントの実行順序 join, on, where
1. 一般的な SELECT ステートメントの完全な実行順序
2) on を使用して結合接続のデータをフィルタリングします。
3) where 句は、指定された条件に基づいてレコード行をフィルタリングします。
4) group by 句はデータを複数のグループに分割します;
5) cube、rollup
6) 計算には集計関数を使用します;
7) Hasting 句を使用しますフィルターのグループ化;
8) すべての式を計算します;
9) 選択フィールドを計算します;
10) データの重複を排除するためにdistinctを使用します
11) 順序を使用しますby 結果セットを並べ替えます。
12) TOPN データを選択します
2.from
3. on
次の 2 つの SQL と結果を見てください。 2 つの違いは、on ステートメントと where ステートメントの後の位置にあります。まず条件付きフィルタリングに on を使用し、次に結合操作を実行してから、where 条件付きフィルタリングを適用します。
最初に join を使用して接続し、次に on を使用してフィルタリングします。これにより、デカルト積が形成されます。このような左結合と直接結合の間に違いはありません。したがって、まず条件でフィルタリングしてから結合する必要があります。
WHERE および ON の後に JOIN 操作が実行される場合、次の 2 つの SQL クエリの結果は同じになるはずです。結合後のセットに対してフィルタリングが行われていることがわかります。
要約すると、まず on 条件フィルタリングを実行し、次に結合し、最後に where フィルタリングを実行しますSELECT DISTINCT a.domain , b.domain
FROM mal_nxdomains_raw a
LEFT JOIN mal_nxdomains_detail b ON a.domain = b.domain AND b.date = ‘20160403'
WHERE a.date = ‘20160403'
SELECT DISTINCT a.domain , b.domain FROM mal_nxdomains_raw a LEFT JOIN mal_nxdomains_detail b ON a.domain = b.domain #and b.date = ‘20160403' WHERE a.date = ‘20160403' AND b.date = ‘20160403'
1、使用位置
on 条件位置在join后面
where 条件在join 与on完成的后面
2、使用对象
on 的使用对象是被关联表
where的使用对象可以是主表,也可以是关联表
3、选择与使用
主表条件筛选:只能在where后面使用。
被关联表,如果是想缩小join范围,可以放置到on后面。如果是关联后再查询,可以放置到where 后面。
如果left join 中,where条件有对被关联表的 关联字段的 非空查询,与使用inner join的效果后,在进行where 筛选的效果是一样的。不能起到left join的作用。
在表A和表B的联接中,从A表中选出一条记录,并将其传递到B表进行扫描和匹配。所以A的行数决定查询次数,B表的行数决定扫描范围。需要运行100次从A表中取出一条数据,然后进行200次比对,将结果存储到B表中。
相对来说从A表取数据消耗的资源比较多。所以尽量tableA选择比较小的表。同时缩小B表的查询范围。
但是实际应用中,因为二者返回的数据结果不同,使用的索引也不同,导致条件放置在on 和 where 效率是不一定谁更好。要根据需求来确定。
以上がmysqlの結合クエリと複数のクエリ方法とは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。