当用Ibatis进行大数据量Sql查询时(如上百万条,千万条数据),如果按照一般的编程方式(如QueryForList方法)把数据查询出来再做操作则很可能会出现性能问题,如: 1.对JVM内存的大量消耗; 2.大量对象的密集创建对GC带来一定的压力; 3.数据查询和后续的数
当用Ibatis进行大数据量Sql查询时(如上百万条,千万条数据),如果按照一般的编程方式(如QueryForList方法)把数据查询出来再做操作则很可能会出现性能问题,如:
1.对JVM内存的大量消耗;
2.大量对象的密集创建对GC带来一定的压力;
3.数据查询和后续的数据操作无法并行执行等
为应对这样的场景,Ibatis提供了RowHandler接口,以回调的方式,允许用户对查询结果集进行自定义的处理,用户通过自定义实现handleRow方法一次处理一条数据,从而提高框架的灵活性。
/** * Event handler for row by row processing. * <p/> * The RowHandler interface is used by the SqlMapSession.queryWithRowHandler() method. * Generally a RowHandler implementation will perform some row-by-row processing logic * in cases where there are too many rows to efficiently load into memory. * <p/> * Example: * <pre class="brush:php;toolbar:false"> * sqlMap.queryWithRowHandler ("findAllEmployees", null, new MyRowHandler())); **/ public interface RowHandler { /** * Handles a single row of a result set. * * This method will be called for each row in a result set. For each row the result map * will be applied to build the value object, which is then passed in as the valueObject * parameter. * * @param valueObject The object representing a single row from the query. * @see com.ibatis.sqlmap.client.SqlMapSession */ void handleRow(Object valueObject); }
简单举例来说RowHandler的作用:
在大数据量的场景下,如:银行每天对账户的“计提”操作,如果有一千万个账户,则需要查询出一千万条账号,然后做一千万次更新(如果可以用addbatch那就肯定不用一千万次了)。为了尽可能提升性能:
1.必须防止对象爆发式的创建,因为爆发式创建会让内存急剧上升,如果没有很好的设计,还会导致对象爆发式的销毁(即:对最后一条数据处理完才会让所有对象失效,而在进行这一千万次更新期间这些内存都是被占用的)。通过自定义RowHandler,可以对数据逐条进行处理,在handleRow方法中执行更新操作,更新完之后立刻释放对象,这样便对操作进行了“离散化”,降低了对内存的占用。
2.上面通过“离散化”解决了内存占用的问题,但查询和数据处理的总时间是没有减少的,为了达到更高的效率,还需要进行“异步化”处理。在handleRow方法中,将valueObject发送到异步队列中,让查询和执行进行并行处理,进而降低总时间。其实总时间的降低体现出的只是一个优点,还有一个优点就是:进行“异步化”之后的查询时间和直接调用QueryForList的查询时间相差不会太大,查询完之后就快速释放连接了,减轻了数据库的压力。
注意事项:
当应用RowHandler时,可能仍然会发现内存急剧上升,这是因为底层JDBC返回的ResultMap仍然会一次性把数据全部返回的缘故。通过设置fetchsize可以解决这一问题,fetchsize是JDBC提供的一个配置变量,JDBC驱动按照该变量的配置值从数据库中循环取数据,而不是一次性load到内存中,这样便允许用户根据自己的实际情况做最优的参数设置,ibatis的select标签将此属性暴露了出来,可以针对某个特定的语句做独立的设置,以达到最优的性能。但是fetchsize也不能太小,否则会带来java和数据库之间频繁的交互,内存问题倒是解决了,但是频繁交互带来的性能问题又出现了,所以fetchsize的值需要以具体场景和实验数据为依据进行灵活设置。
关于fetchsize的几个链接:
http://www.2cto.com/database/201305/209625.html
http://www.java3z.com/cwbwebhome/article/article8/828.html?id=2244
http://www.smithfox.com/?e=153
http://stackoverflow.com/questions/3870500/ibatis-querywithrowhandler-still-seems-to-fetch-all-rows
http://docs.aws.amazon.com/redshift/latest/dg/jdbc-fetch-size-parameter.html
利用rowhandler还可以实现对象关联关系的创建,解决“N+1 Select“的问题,此处不详述,备忘一下,详见《Ibatis in Action》一书的相关章节。
rowhandler可以做的事情其实很多,它是一种公用的机制,只是经常被用来解决效率问题,当Ibatis框架不能满足我们的需求时,可以考虑发挥该接口的作用。
至于性能,本文说的都是偏理论的、一般性的场景,具体的解决方案需要因场景而异,经验结合需求才能得到最好的设计。

MySQLとSQLiteの主な違いは、設計コンセプトと使用法のシナリオです。1。MySQLは、大規模なアプリケーションとエンタープライズレベルのソリューションに適しており、高性能と高い並行性をサポートしています。 2。SQLiteは、モバイルアプリケーションとデスクトップソフトウェアに適しており、軽量で埋め込みやすいです。

MySQLのインデックスは、データの取得をスピードアップするために使用されるデータベーステーブル内の1つ以上の列の順序付けられた構造です。 1)インデックスは、スキャンされたデータの量を減らすことにより、クエリ速度を改善します。 2)B-Tree Indexは、バランスの取れたツリー構造を使用します。これは、範囲クエリとソートに適しています。 3)CreateIndexステートメントを使用して、createIndexidx_customer_idonorders(customer_id)などのインデックスを作成します。 4)Composite Indexesは、createIndexIDX_CUSTOMER_ORDERONORDERS(Customer_Id、Order_date)などのマルチコラムクエリを最適化できます。 5)説明を使用してクエリ計画を分析し、回避します

MySQLでトランザクションを使用すると、データの一貫性が保証されます。 1)StartTransactionを介してトランザクションを開始し、SQL操作を実行して、コミットまたはロールバックで送信します。 2)SavePointを使用してSave Pointを設定して、部分的なロールバックを許可します。 3)パフォーマンスの最適化の提案には、トランザクション時間の短縮、大規模なクエリの回避、分離レベルの使用が合理的に含まれます。

MySQLの代わりにPostgreSQLが選択されるシナリオには、1)複雑なクエリと高度なSQL関数、2)厳格なデータの整合性と酸コンプライアンス、3)高度な空間関数が必要、4)大規模なデータセットを処理するときに高いパフォーマンスが必要です。 PostgreSQLは、これらの側面でうまく機能し、複雑なデータ処理と高いデータの整合性を必要とするプロジェクトに適しています。

MySQLデータベースのセキュリティは、以下の測定を通じて達成できます。1。ユーザー許可管理:CreateUSERおよびGrantコマンドを通じてアクセス権を厳密に制御します。 2。暗号化された送信:SSL/TLSを構成して、データ送信セキュリティを確保します。 3.データベースのバックアップとリカバリ:MySQLDUMPまたはMySQLPumpを使用して、定期的にデータをバックアップします。 4.高度なセキュリティポリシー:ファイアウォールを使用してアクセスを制限し、監査ロギング操作を有効にします。 5。パフォーマンスの最適化とベストプラクティス:インデックス作成とクエリの最適化と定期的なメンテナンスを通じて、安全性とパフォーマンスの両方を考慮に入れます。

MySQLのパフォーマンスを効果的に監視する方法は? MySqladmin、ShowGlobalStatus、PerconAmonitoring and Management(PMM)、MySQL EnterpriseMonitorなどのツールを使用します。 1. mysqladminを使用して、接続の数を表示します。 2。showglobalstatusを使用して、クエリ番号を表示します。 3.PMMは、詳細なパフォーマンスデータとグラフィカルインターフェイスを提供します。 4.mysqlenterprisemonitorは、豊富な監視機能とアラームメカニズムを提供します。

MySQLとSQLServerの違いは次のとおりです。1)MySQLはオープンソースであり、Webおよび埋め込みシステムに適しています。2)SQLServerはMicrosoftの商用製品であり、エンタープライズレベルのアプリケーションに適しています。ストレージエンジン、パフォーマンスの最適化、アプリケーションシナリオの2つには大きな違いがあります。選択するときは、プロジェクトのサイズと将来のスケーラビリティを考慮する必要があります。

高可用性、高度なセキュリティ、優れた統合を必要とするエンタープライズレベルのアプリケーションシナリオでは、MySQLの代わりにSQLServerを選択する必要があります。 1)SQLServerは、高可用性や高度なセキュリティなどのエンタープライズレベルの機能を提供します。 2)VisualStudioやPowerbiなどのMicrosoftエコシステムと密接に統合されています。 3)SQLSERVERは、パフォーマンスの最適化に優れた機能を果たし、メモリが最適化されたテーブルと列ストレージインデックスをサポートします。


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

メモ帳++7.3.1
使いやすく無料のコードエディター

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

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境
