Multi-Resultセットクエリとは、単一のSQLクエリが複数の結果セットを返す状況を指します。通常、このクエリは、複数のSQLステートメントを分離する(セミコロン)によって実行されます。例えば:
<span><span><span class="hljs-keyword">SELECT</span></span><span> </span><span><span class="hljs-operator">*</span></span><span> </span><span><span class="hljs-keyword">FROM</span></span><span> table1;
</span><span><span class="hljs-keyword">SELECT</span></span><span> </span><span><span class="hljs-operator">*</span></span><span> </span><span><span class="hljs-keyword">FROM</span></span><span> table2;
</span></span>上記のクエリは、2つの結果セットを返します。 MySQLの場合、 MySQLI_Multi_Query()関数を介してMulti-Resultセットクエリを実行し、 mysqli_next_result()を介して次の結果に切り替えることができます。
MySQLI拡張機能では、 mysqli_stmt :: store_result()は、サーバーからクライアントへのクエリ結果を保存するために使用される関数です。これは、クエリ結果セットからのデータがデータベースサーバーからクライアントのメモリに完全にロードされることを意味します。データに複数回アクセスするシナリオの場合、 Store_Result()は、データが読み取られるたびにデータベースサーバーとの対話を避けるため、パフォーマンスを向上させることができます。
Multi-Resultセットクエリを実行するとき、各結果セットは独立してデータを返します。 store_result()を誤って使用する場合、次の問題が発生する可能性があります。
高いメモリフットプリント:クエリ結果セットが非常に大きい場合、Calling Store_Result()は結果セット全体をメモリにロードし、過度のメモリフットプリントを引き起こす可能性があります。
結果セットは完全に読み取られていません。MySqli_next_result ()およびstore_result()が適切に呼び出されない場合、マルチリエルトセットクエリでは、いくつかの結果セットが完全に読み取られず、その後のクエリでエラーが発生する場合があります。
実行効率の問題:各クエリでは、データベースから完全なデータセットをロードする必要があるため、 store_result()を過剰に使用するとパフォーマンスの負担が生じます。
まず、 mysqli_multi_query()関数を使用して、マルチ表示セットクエリを実行する必要があります。この関数により、複数のSQLステートメントを実行し、複数の結果セットを返すことができます。それを使用する場合、1つの重要なポイントに注意する必要があります。MySqli_Multi_Query ()はすべてのクエリ結果を返しますが、結果セットを自動的に処理しません。 mysqli_next_result()を介してセットされた各結果を手動で反復する必要があります。
<span><span><span class="hljs-variable">$conn</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-variable">$host</span></span><span>, </span><span><span class="hljs-variable">$user</span></span><span>, </span><span><span class="hljs-variable">$password</span></span><span>, </span><span><span class="hljs-variable">$dbname</span></span><span>);
</span><span><span class="hljs-variable">$sql</span></span><span> = </span><span><span class="hljs-string">"SELECT * FROM table1; SELECT * FROM table2;"</span></span><span>;
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$conn</span></span><span>-></span><span><span class="hljs-title function_ invoke__">multi_query</span></span><span>(</span><span><span class="hljs-variable">$sql</span></span><span>)) {
</span><span><span class="hljs-keyword">do</span></span><span> {
</span><span><span class="hljs-comment">// 現在の結果セットを取得します</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-variable">$conn</span></span><span>-></span><span><span class="hljs-title function_ invoke__">store_result</span></span><span>()) {
</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$row</span></span><span> = </span><span><span class="hljs-variable">$result</span></span><span>-></span><span><span class="hljs-title function_ invoke__">fetch_assoc</span></span><span>()) {
</span><span><span class="hljs-comment">// データの各行を処理します</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Data: "</span></span><span> . </span><span><span class="hljs-variable">$row</span></span><span>[</span><span><span class="hljs-string">'column_name'</span></span><span>] . </span><span><span class="hljs-string">"\n"</span></span><span>;
}
</span><span><span class="hljs-variable">$result</span></span><span>-></span><span><span class="hljs-title function_ invoke__">free</span></span><span>(); </span><span><span class="hljs-comment">// 現在の結果セットをリリースします</span></span><span>
}
} </span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$conn</span></span><span>-></span><span><span class="hljs-title function_ invoke__">next_result</span></span><span>()); </span><span><span class="hljs-comment">// 次の結果セットを取得します</span></span><span>
}
</span><span><span class="hljs-variable">$conn</span></span><span>-></span><span><span class="hljs-title function_ invoke__">close</span></span><span>();
</span></span>store_result()はクエリ結果全体をメモリにロードするため、大量のデータを処理するとメモリが不十分な場合があります。メモリを効率的に管理するには、各結果セットが処理された後、 $ result-> free()を使用してメモリスペースを解放することをお勧めします。
特にクエリの結果のみを一度に読み取る必要がある場合、すべてのクエリがstore_result()の使用を必要とするわけではありません。単純な選択クエリの場合、データの一部のみを取得する必要があり、クエリの結果が小さい場合は、 bind_result()またはfetch()を使用してstore_result()を使用する代わりにデータを取得することを検討できます。これにより、メモリ消費が削減されます。
<span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$conn</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM table1"</span></span><span>);
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>();
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">bind_result</span></span><span>(</span><span><span class="hljs-variable">$column1</span></span><span>, </span><span><span class="hljs-variable">$column2</span></span><span>);
</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">fetch</span></span><span>()) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Data: "</span></span><span> . </span><span><span class="hljs-variable">$column1</span></span><span> . </span><span><span class="hljs-string">", "</span></span><span> . </span><span><span class="hljs-variable">$column2</span></span><span> . </span><span><span class="hljs-string">"\n"</span></span><span>;
}
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">close</span></span><span>();
</span></span>結果セットが非常に大きい場合は、クエリを複数のページングクエリに分割することを検討してください。クエリごとに返されるレコードの数を制限することにより、1回のロードされたデータの量が減少し、それにより効率が向上し、メモリの使用量が減少します。
<span><span><span class="hljs-variable">$page</span></span><span> = </span><span><span class="hljs-number">1</span></span><span>;
</span><span><span class="hljs-variable">$perPage</span></span><span> = </span><span><span class="hljs-number">10</span></span><span>;
</span><span><span class="hljs-variable">$offset</span></span><span> = (</span><span><span class="hljs-variable">$page</span></span><span> - </span><span><span class="hljs-number">1</span></span><span>) * </span><span><span class="hljs-variable">$perPage</span></span><span>;
</span><span><span class="hljs-variable">$sql</span></span><span> = </span><span><span class="hljs-string">"SELECT * FROM table1 LIMIT <span class="hljs-subst">$offset</span></span></span><span>, </span><span><span class="hljs-subst">$perPage</span></span><span>";
</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-variable">$conn</span></span><span>-></span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-variable">$sql</span></span><span>);
</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$row</span></span><span> = </span><span><span class="hljs-variable">$result</span></span><span>-></span><span><span class="hljs-title function_ invoke__">fetch_assoc</span></span><span>()) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Data: "</span></span><span> . </span><span><span class="hljs-variable">$row</span></span><span>[</span><span><span class="hljs-string">'column_name'</span></span><span>] . </span><span><span class="hljs-string">"\n"</span></span><span>;
}
</span></span>Multi-ResultセットクエリでStore_Result()を効率的に使用するために、コードに実行時間監視を追加して、クエリがパフォーマンスボトルネックを引き起こしたかどうかを判断することができます。クエリが遅すぎる場合は、SQLステートメントを最適化するか、段階的に実行することを検討できます。
<span><span><span class="hljs-variable">$start_time</span></span><span> = </span><span><span class="hljs-title function_ invoke__">microtime</span></span><span>(</span><span><span class="hljs-literal">true</span></span><span>);
</span><span><span class="hljs-comment">// クエリを実行します</span></span><span>
</span><span><span class="hljs-variable">$end_time</span></span><span> = </span><span><span class="hljs-title function_ invoke__">microtime</span></span><span>(</span><span><span class="hljs-literal">true</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Query Time: "</span></span><span> . (</span><span><span class="hljs-variable">$end_time</span></span><span> - </span><span><span class="hljs-variable">$start_time</span></span><span>) . </span><span><span class="hljs-string">" seconds"</span></span><span>;
</span></span>
関連タグ:
mysqli_stmt